Why so much memory?
I have a 1000x1500 pixel bitmap of which I want to make a mutable copy in Android.
When I run the following code...
// int width = original.getWidth(); // 1000px
// int height = original.getHeight(); // 1500px
final Bitmap result = original.copy(original.getConfig(), true);
original.recycle();
...I get an OutOfMemoryError
on the copy
line:
java.lang.OutOfMemoryError: bitmap size exceeds VM budget
ERROR/GraphicsJNI(419): VM won't let us allocate 6000000 bytes
Why does the copy instruction need 6MB (!) for a 1000x1500 pixel bitmap?
How can I create a mutable bitmap from a non-mutable one in more memory-efficient way?
Edit
BitmapFactory returns inmutable bitmaps. Apparently, the only way of creating a mutable bitmap from an immutable one is to copy it into a new mutable bitmap. In the case of a 1000x1500 bitmap, this apparently requires 12MB (1000x1500x4x2), which causes an OutOfMemoryError in most Android devices.
Is this problem unsolvable in Android then开发者_高级运维?
To answer your first question:
1000*1500*32/8=6000000
(32 bits/pixel for color information)
To answer your second question: you need to reduce the size of the image, either by processing it in chunks, or be reducing the resolution or color depth.
cdonner put me in the right direction.
Turns out that the original bitmap was using ARGB_8888, which requires 32 bits per pixel and is more than what was needed for this particular app.
Changing the bitmap config to RGB_565, which requires 16 bits per pixel, reduced memory consumption by half.
There is a tricky workaround which I used to avoid OutOfMemoryError. I registered a receiver so that it ran on different process:
<receiver android:name=".ImageTransformReceiver"
android:exported="true" android:process=":imageTransformProcess"/>
Inside a receiver I do expensive memory operations (loading of two large images and merging them into one). I write the result image into file and send broadcast back to main process referring to the result image file path in Intent.
This is just a hack that allows you to use more OS memory inside one application. Hope this helps.
As of API level, 11 BitmapFactory.Options has a boolean 'inMutable' which can be set to produce mutable Bitmaps.
While this doesn't change the memory use for the individual bitmap, it will save you from having to store two copies in memory.
精彩评论