0

After searching SO and reading lots of answers I wrote the following code to get the minimum value of inSampleSize for downsampling a large bitmap:

public Bitmap load(Context context, String image_url) throws Exception {
    BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();

    bitmapOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(image_url, bitmapOptions);

    final float imageSize = (float) bitmapOptions.outWidth * (float) bitmapOptions.outHeight * 4.0f / 1024.0f / 1024.0f; // MB

    bitmapOptions.inSampleSize = (int) Math.pow(2, Math.floor(imageSize / MemoryManagement.free(context)));
    bitmapOptions.inJustDecodeBounds = false;

    return BitmapProcessing.modifyOrientation(BitmapFactory.decodeFile(image_url, bitmapOptions), image_url);
}

And

public class MemoryManagement {

    public static float free(Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        int memoryClass = am.getMemoryClass() - 10;
        if (memoryClass < 1) memoryClass = 1;
        return (float) memoryClass;
    }

}

The goal is to get the maximum dimension of bitmap sample without any OutOfMemory exception. Could I trust this code?

  • can you explain it to me to learn what you are going to do? – mmlooloo Sep 17 '14 at 16:53
  • @mmlooloo I need to load a bitmap and apply some effects on it. so I tried to find the minimum value of `inSampleSize` to get the maximum dimension of bitmap sample without any OOM exception. –  Sep 17 '14 at 16:57

2 Answers2

1

I think that you can upgrade the heap test to 16 majority of device have a Java heap limited to 16 some even 24

something like

public class MemoryManagement {

    public static float free(Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        int memoryClass = am.getMemoryClass() - 16;
        if (memoryClass < 1) memoryClass = 1;
        return (float) memoryClass;
    }

}
Nadir Belhaj
  • 11,953
  • 2
  • 22
  • 21
0

if the heap size is limited to 16MB what Nadir returns is 1MB which means you must scaled for example 20MB picture to 1MB space but you can use for example 10MB so my solution is dynamically scaling that means always use 0.6 of memory space for your images regardless of heap size is 16MB or 24MB or etc:

    public class MemoryManagement {

    public static float free(Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        int memoryClass = am.getMemoryClass();
        memoryClass = ((memoryClass *3)/5); // use 0.6 of your memory 
        if (memoryClass < 1) memoryClass = 1;
        return (float) memoryClass;
      }
   }
mmlooloo
  • 18,937
  • 5
  • 45
  • 64