Resize a large bitmap file to scaled output file on Android Resize a large bitmap file to scaled output file on Android android android

Resize a large bitmap file to scaled output file on Android


No. I'd love for someone to correct me, but I accepted the load/resize approach you tried as a compromise.

Here are the steps for anyone browsing:

  1. Calculate the maximum possible inSampleSize that still yields an image larger than your target.
  2. Load the image using BitmapFactory.decodeFile(file, options), passing inSampleSize as an option.
  3. Resize to the desired dimensions using Bitmap.createScaledBitmap().


Justin answer translated to code (works perfect for me):

private Bitmap getBitmap(String path) {Uri uri = getImageUri(path);InputStream in = null;try {    final int IMAGE_MAX_SIZE = 1200000; // 1.2MP    in = mContentResolver.openInputStream(uri);    // Decode image size    BitmapFactory.Options options = new BitmapFactory.Options();    options.inJustDecodeBounds = true;    BitmapFactory.decodeStream(in, null, options);    in.close();    int scale = 1;    while ((options.outWidth * options.outHeight) * (1 / Math.pow(scale, 2)) >           IMAGE_MAX_SIZE) {       scale++;    }    Log.d(TAG, "scale = " + scale + ", orig-width: " + options.outWidth + ",        orig-height: " + options.outHeight);    Bitmap resultBitmap = null;    in = mContentResolver.openInputStream(uri);    if (scale > 1) {        scale--;        // scale to max possible inSampleSize that still yields an image        // larger than target        options = new BitmapFactory.Options();        options.inSampleSize = scale;        resultBitmap = BitmapFactory.decodeStream(in, null, options);        // resize to desired dimensions        int height = resultBitmap.getHeight();        int width = resultBitmap.getWidth();        Log.d(TAG, "1th scale operation dimenions - width: " + width + ",           height: " + height);        double y = Math.sqrt(IMAGE_MAX_SIZE                / (((double) width) / height));        double x = (y / height) * width;        Bitmap scaledBitmap = Bitmap.createScaledBitmap(resultBitmap, (int) x,            (int) y, true);        resultBitmap.recycle();        resultBitmap = scaledBitmap;        System.gc();    } else {        resultBitmap = BitmapFactory.decodeStream(in);    }    in.close();    Log.d(TAG, "bitmap size - width: " +resultBitmap.getWidth() + ", height: " +        resultBitmap.getHeight());    return resultBitmap;} catch (IOException e) {    Log.e(TAG, e.getMessage(),e);    return null;}


This is 'Mojo Risin's and 'Ofir's solutions "combined". This will give you a proportionally resized image with the boundaries of max width and max height.

  1. It only reads meta data to get the original size (options.inJustDecodeBounds)
  2. It uses a rought resize to save memory (itmap.createScaledBitmap)
  3. It uses a precisely resized image based on the rough Bitamp created earlier.

For me it has been performing fine on 5 MegaPixel images an below.

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