I'm building an imagepicker in my Android app, for which I used the example code on this page. This basically gives me a button which opens the possibility to get a file from the SD card, or one by taking a picture. Once I selected an image, it displays the image using a simple ImageView. In general, this works perfectly well; I can select an image, then click the select image button again and select another image. So far so good.. with small files that is.
The problem starts, when I use "larger files"; pictures I simply took with the built-in phone camera. I can select one, and that works well. When I hit the select-image button again and select another image, I get an OutOfMemoryError on this line (line 75 of the linked to page):
bitmap = BitmapFactory.decodeFile(path);
My test-device is quite a modern one (Galaxy S4 Mini), so that shouldn't be the problem. Since I need to send the image as a base64 string to an API for which I need to resize it anyway, I can resize the image using something like this:
Bitmap yourBitmap;
Bitmap resized = Bitmap.createScaledBitmap(yourBitmap, newWidth, newHeight, true);
But unfortunately, for this I first need to decode the file, which actually causes the problem in the first place.
So my question is; is there a way that I can resize the image before I decode it to a bitmap? All tips are welcome!
Basically, you should use
BitmapFactory.decodeFile(path, options)
passingBitmap.Options.inSampleSize
to decode a subsampled version of the original Bitmap.Your code will look something like this:
And the calculateInSampleSize code:
to avoid this error,aquire large heap using this in manifest:
then decode bitmap, re-size according to your need
While you load large bitmap files, BitmapFactory class provides several decoding methods (decodeByteArray(), decodeFile(), decodeResource(), etc.).
STEP 1
Setting the inJustDecodeBounds property to true while decoding avoids memory allocation, returning null for the bitmap object but setting outWidth, outHeight and outMimeType. This technique allows you to read the dimensions and type of the image data prior to construction (and memory allocation) of the bitmap.
To avoid java.lang.OutOfMemory exceptions, check the dimensions of a bitmap before decoding it.
STEP 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.
Here’s a method to calculate a sample size value that is a power of two based on a target width and height:
Please read this link for details. http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
try this i have used it once . it worked for me.
You can use image sampling which is loading the smaller size image without having to load the bigger one. You can do that with
Options
argument passed to BitmapFactory. SetOptions.inJustDecodeBounds
true
and BitmapFactory will set Options.outWidth and Options.outHeight fields to image's original size. Note that when setting inJustDecodeBounds to true the returned Bitmap is null. Also use Options.inSampleSize to decode sampled image. Sample size shows how much the result image is scaled down.