How do I reduce the quality of an image in byte format on Android?

旧街凉风 提交于 2019-12-11 03:56:14

问题


Using resources from StackOverflow and other helpful websites, I was successful in creating an application that can upload an image taken by the camera application on an Android phone. The only trouble is, the phone I have right now takes very high-quality pictures, resulting in a long wait-time for uploads.

I read about converting images from jpeg to a lower rate (smaller size or just web-friendly sizes), but the code I am using right now saves the captured image as a byte (see code below). Is there any way to reduce the quality of the image in the form that it is in, or do I need to find a way to convert it back to jpeg, reduce the image quality, and then place it back in byte form?

Here is the code snippet I'm working with:

    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());
            }
        }
    }
}

回答1:


For web apps, you definitely don't need the 5+ MP images that cameras produce; image resolution is the primary factor in image size, so I'd suggest you use the BitmapFactory class to produce a downsampled bitmap.

Particularly, look at BitmapFactory.decodeByteArray(), and pass it a BitmapFactory.Options parameter indicating you want a downsampled bitmap.

// 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);

For more info, take a look at the Android Training lesson on displaying bitmaps efficiently and the reference for BitmapFactory:

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

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




回答2:


To tell the decoder to subsample the image, loading a smaller version into memory, set inSampleSize to true in your BitmapFactory.Options object. For example, an image with resolution 2048x1536 that is decoded with an inSampleSize of 4 produces a bitmap of approximately 512x384. Loading this into memory uses 0.75MB rather than 12MB for the full image (assuming a bitmap configuration of ARGB_8888). see this

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;
 }


来源:https://stackoverflow.com/questions/13809445/how-do-i-reduce-the-quality-of-an-image-in-byte-format-on-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!