【问题标题】:Resizing image before upload (my upload take/pick is ok)上传前调整图像大小(我的上传拍摄/选择没问题)
【发布时间】:2014-10-13 07:57:22
【问题描述】:

差不多两周后...我放弃了!!!

我实现了从图库和相机上传图片...

startActivityForResult... ok!  
EXTERNAL_CONTENT_URI... ok!  
ACTION_IMAGE_CAPTURE... ok!  
onActivityResult... ok!  
Activity.RESULT_OK ('cause I'm on Fragment)... ok!  
getActivity().getContentResolver().query()... ok!  
BitmapFactory.Options, opts.inSampleSize, .decodeFile... ok!  

但是在上传到服务器之前,我无法将图像的大小减小到 900 像素...

- FileInputStream(sourceFile);  
- HttpURLConnection  
- DataOutputStream( getOutputStream)  
- dos.writeBytes(form... name... file name...)
- dos.write(buffer, 0, bufferSize) 

我听不懂...
- 在这种情况下如何使用“createScaledBitmap”。
- 如果我在创建新位图时没有路径(至少我认为是这样),我该如何使用“writeBytes(...filename=?)”。
- 如果我在磁盘上有一个原始图像,“createScaledBitmap”的结果路径是什么?
- 缓冲区是如何工作的(Step by Step 会很棒),为什么在 stackoverflow 的其他示例中不使用它?

我阅读了许多参考资料,包括:
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
但我已经使用“options.inSampleSize”在我的片段上进行预览,我认为我需要(在我的情况下)“createScaledBitmap”来实现我的 900x900px 图像进行上传。

如果有其他方法可以上传带有调整大小的图片包括...请告诉我!
(任何链接都会有所帮助)

我知道...我应该使用 AsyncTask...我正在努力! ;)

请考虑不要说那么技术性,因为我有最糟糕的学习 Android 组合:新手和说西班牙语! xD

添加:
有人可以帮忙解决@GVSharma 在这里所说的事情吗?
Upload compressed image

“你首先得到字符串路径na.so将它转换为位图并压缩它。而不是将字符串文件路径作为第一个参数发送给该方法,将第一个参数更改为位图位图。或者你只需​​要字符串文件路径然后再次转换将位图压缩为字符串。希望这个可以帮助你"
(我不知道该怎么做)

public int uploadFile(String sourceFileUri) {

    final String fileName = sourceFileUri;

    HttpURLConnection conn = null;
    DataOutputStream dos = null; 
    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary = "*****";
    int bytesRead, bytesAvailable, bufferSize;
    byte[] buffer;
    int maxBufferSize = 1 * 1024 * 1024;
    File sourceFile = new File(sourceFileUri);

    if (!sourceFile.isFile()) {
         ...
    } else {
        try {      
            // open a URL connection to the Servlet
             FileInputStream fileInputStream = new FileInputStream(sourceFile);
             URL url = new URL(upLoadServerUri);

             conn = (HttpURLConnection) url.openConnection();
             conn.setDoInput(true);
             conn.setDoOutput(true);
             conn.setUseCaches(false);
             conn.setRequestMethod("POST");
             conn.setRequestProperty("Connection", "Keep-Alive");
             conn.setRequestProperty("ENCTYPE", "multipart/form-data");
             conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
             conn.setRequestProperty("uploaded_file", fileName);//This is just for info?

             dos = new DataOutputStream(conn.getOutputStream());
             dos.writeBytes(twoHyphens + boundary + lineEnd);
             dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\"; filename=\""+fileName+"\"" + lineEnd);//How put in here a resized bitmap?
             dos.writeBytes(lineEnd);

             //Here I'm lost!
             bytesAvailable = fileInputStream.available();
             bufferSize = Math.min(bytesAvailable, maxBufferSize);
             buffer = new byte[bufferSize];

             bytesRead = fileInputStream.read(buffer, 0, bufferSize); 

             //I think...
             //this is a way to transfer the file in little pieces to server, right?, wrong?
             //If anybody can explain this, step by step... THANKS!!!
             while (bytesRead > 0) {
                dos.write(buffer, 0, bufferSize);
                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);
              }
             dos.writeBytes(lineEnd);
             dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
             serverResponseCode = conn.getResponseCode();
             String serverResponseMessage = conn.getResponseMessage();
             Log.i("uploadFile", "Respuesta HTTP es: " + serverResponseMessage + ": " + serverResponseCode);

             if(serverResponseCode == 200){
                 ...               
             }
             fileInputStream.close();
             dos.flush();
             dos.close();
        } catch (MalformedURLException ex) {
            ...
        } catch (Exception e) { 
            ... 
        }

        dialog.dismiss();      
        return serverResponseCode;

    } // End else block
}//End uploadFile()

【问题讨论】:

  • 如果您只调整位图大小,请转到stackoverflow.com/questions/15759195/…
  • @DivyangMetalia 谢谢!这很有帮助!如果您知道我如何在帖子中添加该位图...请告诉我。
  • 您可以将位图转换为Base64并上传。
  • @DivyangMetalia 可能不知道我在说什么,但我读到使用 BASE64 会导致某些设备内存不足......这是真的吗?
  • 是的,当您的位图尺寸很大时,某些设备会抛出内存不足错误。但在这里你可以上传 900px 所以它上传。我认为您可以尝试使用 base64 进行图片上传。

标签: android upload resize


【解决方案1】:

实际上有两种方法可以处理上述情况,如下所述:

1] 在服务器端(在您的网络服务中)进行一些安排,以便您可以在服务器上上传图像时传递高度和宽度,这将减小您传递的任何高度/宽度尺寸的图像大小。这是第一个解决方案。

2] 根据我的理解,如果您可以通过此代码减小位图尺寸:

try
{
int inWidth = 0;
int inHeight = 0;

InputStream in = new FileInputStream(pathOfInputImage);

// decode image size (decode metadata only, not the whole image)
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, options);
in.close();
in = null;

// save width and height
inWidth = options.outWidth;
inHeight = options.outHeight;

// decode full image pre-resized
in = new FileInputStream(pathOfInputImage);
options = new BitmapFactory.Options();
// calc rought re-size (this is no exact resize)
options.inSampleSize = Math.max(inWidth/dstWidth, inHeight/dstHeight);
// decode full image
Bitmap roughBitmap = BitmapFactory.decodeStream(in, null, options);

// calc exact destination size
Matrix m = new Matrix();
RectF inRect = new RectF(0, 0, roughBitmap.getWidth(), roughBitmap.getHeight());
RectF outRect = new RectF(0, 0, dstWidth, dstHeight);
m.setRectToRect(inRect, outRect, Matrix.ScaleToFit.CENTER);
float[] values = new float[9];
m.getValues(values);

// resize bitmap
Bitmap resizedBitmap = Bitmap.createScaledBitmap(roughBitmap, (int) (roughBitmap.getWidth() * values[0]), (int) (roughBitmap.getHeight() * values[4]), true);

// save image
try
{
    FileOutputStream out = new FileOutputStream(pathOfOutputImage);
    resizedBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
}
catch (Exception e)
{
    Log.e("Image", e.getMessage(), e);
}
}
catch (IOException e)
{
   Log.e("Image", e.getMessage(), e);
}

完成上述编码步骤后,您就可以使用您的图像/位图上传逻辑/代码了。

【讨论】:

  • 实际上,如果你想完全重新缩放图像,那么你不能去解释
  • 我想明白了... 1:你得到原始图像的宽度和高度。 2:创建一个有点缩放的位图(我不知道为什么),我认为dstWidth和dstHeight是我想要的像素,但我不知道math.max是如何工作的,这一步让我感到困惑。 3:将 inRect 缩放为 outRect。 4:创建一个新尺寸的位图。 5:压缩位图。类似的东西?
  • 这对我来说是一个很好的新方法......我已经看到很多调整图像大小的例子,但问题是,我不知道如何在没有来自 SD 的路径的情况下使用该位图设备? :S
猜你喜欢
  • 2014-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-19
  • 2019-03-07
  • 2015-08-06
相关资源
最近更新 更多