Bruno Oliveira
Bruno Oliveira

Reputation: 5076

How can I tell the dimensions of a bitmap before loading it? Can I load just a "preview" or "thumbnail" version?

I'm trying to load and display a screen that shows thumbnails of several photos. When I try to load them all as Bitmap's, I often get an OutOfMemoryError because the bitmaps are somewhat large, and I'm loading 10-20 of them depending on the screen size. The photos aren't all the same size, so depending on which subset I'm about to show, the memory may or may not be enough to load them all, making my app crash erratically (sometimes it crashes mid-scroll as the user is scrolling the photo grid).

Note: since I'm showing thumbnails, I don't actually require the loaded bitmaps to come at full resolution. Is there a way to tell what's the size of a bitmap before loading it, and, also, is there a way to load just a "preview" or a downsampled version of a bitmap on disk so I can save memory and avoid hitting the memory limit?

Upvotes: 0

Views: 1162

Answers (1)

Bruno Oliveira
Bruno Oliveira

Reputation: 5076

Yes, when you are loading bitmaps through a BitmapFactory, you can use BitmapFactory.Options to specify that you only want to inspect the bitmap's type, width and height:

// Read bitmap size and type only
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imagePath, options);

int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;

BitmapFactory.Options also allows you to specify that you want to load a downsampled version of a bitmap; all you have to do is specify inSampleSize, which is the downsampling factor (use 2 to load an image that's half the width and half the height -- and hence has about 1/4 of the memory footprint). So in your case, all you have to do is calculate the appropriate downsample factors as appropriate to your thumbnail size, and load the downsampled images:

// (continuing from previous block of code)    

// Calculate downsample factor
options.inSampleSize = /* calculate downsample factor here as appropriate */

// Load a downsampled bitmap according to factor calculated above
options.inJustDecodeBounds = false;
Bitmap myBitmap = BitmapFactory.decodeResource(res, resId, options);

Also, if your list scrolls, then you should probably implement a smart strategy to release the bitmaps that you are no longer showing onscreen. Combined with this technique, this should probably solve your problems with OutOfMemoryError's.

For more information about this, take a look this class on Android Training, which presents these (and many other) handy tips to make sure your app is loading, displaying and processing bitmaps appropriately:

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

Upvotes: 4

Related Questions