1

The method throws OutOfMemoryError for large images in size( not by resolution) i have 12 MP photos, all of them are different in size(1.5MB, 2.5MB, 3.2MB, 4.1MB) etc and the resolution for all of them are same 4000 x 3000 (pixels).

The resizer method works fine for images less than 3MB in size, but for those images that are>3MB it throws OutOfMemoryError i dont know what could fix it, my app is mainly for resizing large images, and this is really getting me nowhere.

The resizer method is:

public File resizeBitmap(String imPath, int reqSize) {
 File fl = null;
 try{
 // First decode with inJustDecodeBounds=true to check dimensions
 final BitmapFactory.Options options = new BitmapFactory.Options();
 options.inJustDecodeBounds = true;
 BitmapFactory.decodeFile(imPath, options);
 // Calculate inSampleSize
 options.inSampleSize = calculateInSampleSize(options, reqSize);
 // Decode bitmap with inSampleSize set
 options.inJustDecodeBounds = false;
 Bitmap saveImg = BitmapFactory.decodeFile(imPath, options);
 //save resized image
 String tmpName = "IMG_"+String.valueOf(System.currentTimeMillis()) + ".jpg";
 fl = fileCache.getRawFile(tmpName);
 FileOutputStream fos = new FileOutputStream(fl);
 saveImg.compress(Bitmap.CompressFormat.JPEG, 95, fos);
 saveImg.recycle();
 return fl;
}
catch (Throwable eex){
 eex.printStackTrace();
 if(eex instanceof OutOfMemoryError) {
 runOnUiThread(new Runnable() {
 public void run() {
 Toast.makeText(Resizer.this, "Memory ran out", Toast.LENGTH_SHORT).show();
 }
 });
 }
 return null;
 }
}
//Method for calculating insamplesize
public int calculateInSampleSize(BitmapFactory.Options options, int reqSize) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
Log.i("width",""+width);
Log.i("height",""+height);
int inSampleSize = 1;
if (height > reqSize || width > reqSize) {
 if (width > height) {
 inSampleSize = Math.round((float) height / (float) reqSize);
 } else {
 inSampleSize = Math.round((float) width / (float) reqSize);
 }
}
return inSampleSize;

}

//Stacktrace
04-11 09:01:19.832: W/System.err(8832): java.lang.OutOfMemoryError
04-11 09:01:19.953: W/System.err(8832): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
04-11 09:01:19.972: W/System.err(8832): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:529)
04-11 09:01:19.993: W/System.err(8832): at com.scale.app.Resizer.resizeBitmap(Resizer.java:1290)
asked Apr 11, 2014 at 9:38
2
  • 1
    Increase your SampleSize. Commented Apr 11, 2014 at 9:41
  • please follow this link : OUT OF MEMORY Commented Apr 11, 2014 at 9:41

3 Answers 3

1

Read Article

Image Size : 4000*3000 in px

When the image load : 4000*3000*4 = ? KB

So,Vitrual Heap Memory of the Android device are : 32 MB, 64 MB , 128 MB ... so on

if you using:

<application
 android:largeHeap="true">
</application>

This will increase the VHM double (if 32 MB = 2* 32 MB). BUt this will not an good way to do this, effect on OS

You need to decrease the size of the image.


Use the below class and pass the path of the image and width , height what you want

Bitmap bitmap = BitmapSize.getDecodedBitmap(path, 400, 400);

Class::::

public class BitmapSize{
public static Bitmap getDecodedBitmap(String path, float target_width, float target_height) {
 Bitmap outBitmap = null;
 try {
 Options decode_options = new Options();
 decode_options.inJustDecodeBounds = true;
 BitmapFactory.decodeFile(path,decode_options); //This will just fill the output parameters
 int inSampleSize = calculateInSampleSize(decode_options, target_width, target_height);
 Options outOptions = new Options();
 outOptions.inJustDecodeBounds = false;
 outOptions.inSampleSize = inSampleSize;
 outOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
 outOptions.inScaled = false;
 Bitmap decodedBitmap = BitmapFactory.decodeFile(path,outOptions);
 outBitmap = Bitmap.createScaledBitmap(decodedBitmap,// (int)target_width, (int)target_height, true);
 (int)((float)decodedBitmap.getWidth() / inSampleSize),
 (int)((float)decodedBitmap.getHeight() / inSampleSize), true);
 System.out.println("Decoded Bitmap: Width " + outBitmap.getWidth() + " Height = " + outBitmap.getHeight() + " inSampleSize = " + inSampleSize);
 } catch (Exception e) {
 // TODO: handle exception
 }
 return outBitmap;
}
public static int calculateInSampleSize(Options options, float reqWidth, float reqHeight) {
 final int height = options.outHeight;
 final int width = options.outWidth;
 int inSampleSize = 1;
 if (height > reqHeight || width > reqWidth) {
 final int heightRatio = Math.round((float) height
 / (float) reqHeight);
 final int widthRatio = Math.round((float) width / (float) reqWidth);
 inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
 }
 return inSampleSize;
}
}
answered Apr 11, 2014 at 9:51
Sign up to request clarification or add additional context in comments.

3 Comments

The app is for resizing purpose of captured images, the photos i have is taken on android phone itself with 12 MP camera, the app resizes the big images to transfer over network, images are never displayed but just resized and saved on new location
Wait a minute .. I'll paste code for your solution. MAy be you will get help
wow that did it i just added these two, outOptions.inPreferredConfig = Bitmap.Config.ARGB_8888; outOptions.inScaled = false;
0

Please read http://developer.android.com/training/displaying-bitmaps/load-bitmap.html how to deal with large Bitmaps.

The BitmapFactory class provides several decoding methods (decodeByteArray(), decodeFile(), decodeResource(), etc.) for creating a Bitmap from various sources. Choose the most appropriate decode method based on your image data source. These methods attempt to allocate memory for the constructed bitmap and therefore can easily result in an OutOfMemory exception

answered Apr 11, 2014 at 9:50

Comments

0

Please try with these Option properties..

 BitmapFactory.Options opts=new BitmapFactory.Options();
 opts.inDither=false; //Disable Dithering mode
 opts.inPurgeable=true; //Tell to gc that whether it needs free memory, the Bitmap can be cleared
 opts.inInputShareable=true; //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
 opts.inTempStorage=new byte[32 * 1024];
 opts.inSampleSize = 1;

To reduce the quality of image file increase the number of opts.inSampleSize. Click here for more details

And add one more attribute in Manifest.xml in application tag

android:largeHeap="true"

answered Apr 11, 2014 at 9:46

1 Comment

Can you try opts.inSampleSize = 2; or 3 then check.. pls

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.