1

In my project I need to manipulate a Bitmap and save it.

To manipulate the image I apply a matrix, like this:

Bitmap b = Bitmap.createBitmap(((BitmapDrawable) imageView.getDrawable()).getBitmap(), 0, 0,width, height, matrix, true);

And I save it like this:

b.compress(Bitmap.CompressFormat.JPEG, 100, out);

The problem is that if do that I can get an OOM error if the bitmap is large.

Any suggestion of how to avoid it?

Unfortunately scaling down the Bitmap is not an acceptable solution, because I need to preserve the bitmap quality.

user229044
  • 232,980
  • 40
  • 330
  • 338
Lisa Anne
  • 4,482
  • 17
  • 83
  • 157

1 Answers1

1

I also had quite some OOMs with Bitmaps, especially on older (Samsung) devices. A simple approach you can use is to catch the OOM, initiate the GC and then try again. If it fails again, you can (for example) show an error message to the user.

private void compressBitmap(/* args */) {
    Bitmap b = Bitmap.createBitmap(((BitmapDrawable) imageView.getDrawable()).getBitmap(), 0, 0,width, height, matrix, true);
    b.compress(Bitmap.CompressFormat.JPEG, 100, out);
}

try {
    compressBitmap(/* args */);
} catch(OutOfMemoryError e) {
    System.gc();
    // try again
    try {
        compressBitmap(/* args */);
    } catch(OutOfMemoryError e) {
        System.gc();
        // Inform user about the error. It's better than the app crashing
    }
}

This is however only a workaround. If you really want to effectively prevent OOMs in this situation, I think you have to use the NDK. In any case, it’s better than the app crashing.

patloew
  • 1,090
  • 9
  • 13
  • Good suggestion going native – Lisa Anne Jan 24 '16 at 08:52
  • Point is: even by going native, how is it possible to prevent the OOM? In any case we need to load the bitmap in memory, don't we? And if we load the bitmap in memory we would get a OOM even using native methods, wouldn't we? – Lisa Anne Jan 24 '16 at 15:21
  • I’m no expert with going native, but as far as I know, allocating memory with the NDK does not count against the Java heap, [see question/answers here](http://stackoverflow.com/questions/21520110/android-ndk-dalvik-heap-and-native-heap-how-separate-between-the-two). Therefore, if you load and manipulate your Bitmap there, it should not lead to any OOMs. – patloew Jan 24 '16 at 15:24