Search code examples
androidimageviewbitmapfactory

What is the use of decoding bitmapfactory twice?


I came across this on the developer's website on the Loading Large Bitmaps Efficiently tutorial.

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
    int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    **BitmapFactory.decodeResource(res, resId, options);**

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

My question is what is the point of decoding resources for the first time where you can set the inSampleSize and then decoding it.


Solution

  • This is common strategy when downloading images.

    Since you almost never want to download an image with higher a resolution than can be displayed, and since Android is quite difficult when it comes to memory management, this system allows you to first assess what size the image is going to be, and when you actually download, you can control how much down-sampling you want.

    Down-sampling, simply put, means how many pixels you're going to skip. For example, downsampling of 1 does no reduction. Downsampling of 2 however, will skip every other pixel both horizontally and vertically, resulting in a bitmap of half the width and half the height, and one quarter the memory.

    If you'll look at this code:

    final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        **BitmapFactory.decodeResource(res, resId, options);**
    

    What's happening here is when calling "decodeResource", you're passing an Options object with inJustDecodeBounds = true. This is telling the BitmapFactory to not actually load the image pixels, but instead, just decode the bounds of the image - a much cheaper operation. When you do this, the result of BitmapFactory is null, but the parameters of Options (outWidth, outHeight) will have valid values describing the width / height of the image. With this, you can compute what sample size you want, and eventually download the actual image, but with a size which is optimal for your application.