glenatron
glenatron

Reputation: 11362

How to find an image size that will not trigger an OutOfMemoryException in Android?

My app takes an image using the device camera, then opens it so the user can perform some processing. To do this I check the image orientation and rotate it if necessary, which I do like this:

       Bitmap image = MediaStore.Images.Media.getBitmap(this.getContentResolver(), lastTaken);
        int rotation = getCameraPhotoOrientation(filePath);
        if (0 < rotation)
        {
            Matrix mx = new Matrix();
            mx.setRotate((float) rotation);
            image = Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), mx, true);
        }

This code works on most devices, however on one of the older test devices I have been using, it causes an OutOfMemoryException when the image is rotated, presumably because it is trying to hold two copies of the image in memory.

How can I avoid this?

If there isn't an easy way to prevent the problem at this point in the process, is there a way that I can test how much memory I have available and limit the image resolution the camera uses to one that will leave enough room for this operation? I'm already specifying resolution, so it is really a question of how I can compare the image size and available memory to figure out what resolution would be safe. My one constraint is that the changes the user makes have to be on the original image, so editing a smaller copy of the image won't cut it, unless there is an easy way to reflect those changes on the stored version. Consequently downsizing the image to something that can be supported in memory wouldn't be a disaster by any means.

Upvotes: 0

Views: 38

Answers (2)

glenatron
glenatron

Reputation: 11362

I couldn't find a way to figure out the amount of memory available and how much I would need, but after finding some other questions on this topic I found that the best solution for me was to enable the largeHeap element in the application manifest - that resolved the crash for me, although it didn't answer the question and after further reading I suspect there is no satisfactory way to do this as things stand.

Upvotes: 0

Asutosh Panda
Asutosh Panda

Reputation: 1473

What is the size of your image? Did you check for possible memory leaks in the App?

Anyways, one way is, you can try to reuse the memory allocated to the first Bitmap after a new second Bitmap content is created. As per Android docs here - https://developer.android.com/topic/performance/graphics/manage-memory ,

Android 3.0 (API level 11) introduces the BitmapFactory.Options.inBitmap field. If this option is set, decode methods that take the Options object will attempt to reuse an existing bitmap when loading content. This means that the bitmap's memory is reused, resulting in improved performance, and removing both memory allocation and de-allocation.

You can set your Bitmap image to be recycled when a new Bitmap is created.

Upvotes: 1

Related Questions