Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android loading of large bitmaps

I'm making an Android app and I need to load an image (bitmap) in a cavas and resize it using the "pinch zoom" gesture. When the image is over a certain size, however, the application crashes (OutOfMemory exception). How do I optimize the loading and manipulation of the image?

To load the image I use:

BitmapFactory.decodeResource (ctx.getResources (), R.drawable.image)

To draw it:

imgCanvas.drawBitmap (image, posX, posY, null), 

To change its size:

Bitmap.createScaledBitmap (originalBitmap, neww, NEWH, true);
like image 397
Giammy Avatar asked Mar 10 '13 14:03

Giammy


People also ask

How do you handle bitmaps in Android as it takes too much memory?

Stay organized with collections Save and categorize content based on your preferences. Note: There are several libraries that follow best practices for loading images. You can use these libraries in your app to load images in the most optimized manner.

What is inSampleSize?

inSampleSize. Added in API level 1. public int inSampleSize. If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory. The sample size is the number of pixels in either dimension that correspond to a single pixel in the decoded bitmap.


1 Answers

This is not trivial.

Based on the current scale of the image and the currently visible part of the image, only load a part of that image at the appropriate resolution:
https://developer.android.com/reference/android/graphics/BitmapRegionDecoder.html

When zoomed-out and you want to show the entire image scaled down, use the methods from this BitmapRegionDecoder class that take a BitmapFactory.Options parameter and set it inSampleSize to a value larger than 1 (preferably a value that is a power of 2):
https://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize

When zooming in, first zoom in the lower resolution that is already shown (where you used a value of inSampleSize > 1) and lazily load a higher resolution version (where inSampleSize is smaller than the previous value you used) using the BitmapRegionDecoder and fade in the higher resolution version gradually.

When the user zooms in, keep doing this until your inSampleSize is 1.

like image 111
Streets Of Boston Avatar answered Oct 14 '22 08:10

Streets Of Boston