How to load tiles from a large bitmap in Android?
Asked Answered
F

3

8

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,000x10,000 image, I want to split it up into a 10x10 grid of 1,000x1,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?

Fleuron answered 20/1, 2011 at 21:48 Comment(2)
Why can't you break up the one huge image into say 16 different ones?Haha
Because I'm just loading an image from the user's phone.Fleuron
F
19

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 android.graphics.BitmapRegionDecoder that lets you do exactly what you want.

You would for instance do the following:

BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(myStream, false);  
Bitmap region = decoder.decodeRegion(new Rect(10, 10, 50, 50), null);

Easy :)

Fleuron answered 23/2, 2011 at 10:0 Comment(0)
P
0

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.

Precipitant answered 20/1, 2011 at 22:40 Comment(1)
Hi, thanks for that, unfortunately I won't have any control over the images that are used with the application.Fleuron
D
0

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,000x10,000 bitmap.

Dirham answered 25/6, 2012 at 10:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.