2

使用来自 StackOverflow 和其他有用网站的资源,我成功地创建了一个应用程序,该应用程序可以上传由 Android 手机上的相机应用程序拍摄的图像。唯一的问题是,我现在的手机拍的照片质量很高,导致上传的等待时间很长。

我阅读了有关将图像从 jpeg 转换为较低速率(较小尺寸或仅适用于 web 的尺寸)的信息,但我现在使用的代码将捕获的图像保存为一个字节(参见下面的代码)。有什么方法可以降低图像格式的质量,还是我需要找到一种方法将其转换回 jpeg,降低图像质量,然后以字节形式放回?

这是我正在使用的代码片段:

    if (Intent.ACTION_SEND.equals(action)) {

        if (extras.containsKey(Intent.EXTRA_STREAM)) {
            try {

                // Get resource path from intent callee
                Uri uri = (Uri) extras.getParcelable(Intent.EXTRA_STREAM);

                // Query gallery for camera picture via
                // Android ContentResolver interface
                ContentResolver cr = getContentResolver();
                InputStream is = cr.openInputStream(uri);
                // Get binary bytes for encode
                byte[] data = getBytesFromFile(is);

                // base 64 encode for text transmission (HTTP)
                int flags = 1;
                byte[] encoded_data = Base64.encode(data, flags);
                // byte[] encoded_data = Base64.encodeBase64(data);
                String image_str = new String(encoded_data); // convert to
                                                                // string

                ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

                nameValuePairs.add(new BasicNameValuePair("image",
                        image_str));

                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(
                        "http://xxxxx.php");
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                HttpResponse response = httpclient.execute(httppost);
                String the_string_response = convertResponseToString(response);
                Toast.makeText(UploadImage.this,
                        "Response " + the_string_response,
                        Toast.LENGTH_LONG).show();
            } catch (Exception e) {
                Toast.makeText(UploadImage.this, "ERROR " + e.getMessage(),
                        Toast.LENGTH_LONG).show();
                System.out.println("Error in http connection "
                        + e.toString());
            }
        }
    }
}
4

2 回答 2

4

对于网络应用程序,您绝对不需要相机产生的 5+ MP 图像;图像分辨率是图像大小的主要因素,因此我建议您使用 BitmapFactory 类来生成下采样位图。

特别是,查看 BitmapFactory.decodeByteArray(),并将 BitmapFactory.Options 参数传递给它,指示您想要一个下采样的位图。

// your bitmap data
byte[] rawBytes = .......... ;

// downsample factor
options.inSampleSize = 4;  // downsample factor (16 pixels -> 1 pixel)

// Decode bitmap with inSampleSize set
return BitmapFactory.decodeByteArray(rawBytes, 0, rawBytes.length, options);

有关更多信息,请查看有关高效显示位图的 Android 培训课程以及 BitmapFactory 的参考:

http://developer.android.com/training/displaying-bitmaps/index.html

http://developer.android.com/reference/android/graphics/BitmapFactory.html

于 2012-12-10T21:48:53.327 回答
2

要告诉解码器对图像进行二次采样,将较小的版本加载到内存中,请在 BitmapFactory.Options 对象中将 inSampleSize 设置为 true。例如,分辨率为 2048x1536 的图像使用 inSampleSize 为 4 进行解码会生成大约 512x384 的位图。将其加载到内存中使用 0.75MB 而不是 12MB 的完整图像(假设位图配置为 ARGB_8888)。看到这个

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

public   Bitmap decodeSampledBitmapFromResource(
  String pathName) {
int reqWidth,reqHeight;
reqWidth =Utils.getScreenWidth();
reqWidth = (reqWidth/5)*2;
reqHeight = reqWidth;
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
//  BitmapFactory.decodeStream(is, null, options);
BitmapFactory.decodeFile(pathName, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(pathName, options);
}

   public   int calculateInSampleSize(BitmapFactory.Options options,
  int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;

if (height > reqHeight || width > reqWidth) {
  if (width > height) {
    inSampleSize = Math.round((float) height / (float) reqHeight);
  } else {
    inSampleSize = Math.round((float) width / (float) reqWidth);
  }
}
return inSampleSize;
 }
于 2013-01-23T11:21:23.723 回答