If I have a large bitmap file that would normally generate an “Out of memory” exception, how can I load it as tiles? e.g. I have a 10,000×10,000 image, I want to split it up into a 10×10 grid of 1,000×1,000 pixel tiles.
I’ve seen the function
Bitmap.createBitmap(sourceBitmap, x, y, width, height) but it requires my large image as the source input.
How can I get a tile from my input image, without fully loading the input image?
Answer from Romain Guy in Is it possible to chop a bitmap to small pieces without loading the entire thing into memory?:
Android 2.3.3 has a new API called
that lets you do exactly what you
You would for instance do the
BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(myStream, false); Bitmap region = decoder.decodeRegion(new Rect(10, 10, 50, 50), null);
If you’re very lucky, you can find a library that can load chunks of an image from storage rather than loading the entire thing. It depends on the image format, and what libraries are available to read it. Plus, the library will probably be written in C, so you’ll have to port it to Java or use the NDK.
It would be far better to break the image into tiles before it’s placed onto the phone.
If neither of these options work for you, I think you’re out of luck.
If the image is stored as a compressed bitmap, then it’s virtually impossible to calculate where a particular region of the image is located in the file. To find a particular region, you would decode line by line, throwing away the results until you get to row y. You then continue decoding for height rows, throwing away the pixels to the left of your X coordinate and to the right of X+width…. very slow if you’re panning across the bottom of a large bitmap.
Reading between the lines, it appears that the BitmapRegionDecoder() mentioned earlier does this in the background if ‘isShareable’ is true. Otherwise it seems that it may uncompress the image, and store the uncompressed copy. With 1 byte per pixel, it will take 100MB to hold your 10,000×10,000 bitmap.