Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to chop a bitmap to small pieces without loading the entire thing into memory?

I'm working on an image processing application for Android that recognizes music notation from pictures taken of music sheets.

I tried to load the entire image into a Bitmap using the BitmapFactory.decodeFile(imgPath) method, but because my phone doesn't have enough memory I get a "VM heap size" error. To work around this, I'd like to chop the full image into smaller pieces, but I'm not sure how to do that.

I also saw that it was possible to reduce the memory size of the Bitmap by using the inSampleSize property of the BitmapFactory.Option class, but if I do that I won't get the high resolution image I need for the music notation recognition process.

Is there anyway to handle this without going to NDK?

like image 409
OffCS Avatar asked Jan 27 '11 10:01

OffCS


3 Answers

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 :)

like image 103
Romain Guy Avatar answered Nov 14 '22 02:11

Romain Guy


If it's from a camera the image will likely be jpeg format. You could use an external jpeg library - either in java or via the NDK, whatever you can find - to give you better control and load it a piece at a time. If you need it as an android.graphics.Bitmap then I suspect you will then need to re-encode the subimage as PNG or JPEG and pass it to BitmapFactory.decodeByteArray(). (If memory is a concern then do be sure to forget your references to the pieces of the bitmap promptly so that the garbage collector can run effectively.)

The same technique will also work if the input graphic is PNG format, or just about anything else provided you can find suitable decode code for it.

I think that by loading the image piecewise you are setting yourself an algorithmic challenge in deciding what parts of it you are really interested in the full detail of. I notice that BitmapFactory.Options includes the option to subsample, that might be useful if you want to analyse an overview of the image to decide what regions to load in full detail.

like image 32
crazyscot Avatar answered Nov 14 '22 03:11

crazyscot


If you're dealing with JPEG images, see my answer to this question as well as this example.

I don't know how possible it is to get libijg on Android, but if it is, then it's worth a shot.

like image 1
mpenkov Avatar answered Nov 14 '22 03:11

mpenkov