Search code examples
androidgraphicsmemory-limit

Viewing a small region of a Large Image in Android


In a gist this is what I want to do:

I want to load a 100x100 region (any part) of a 5mega pixel Image into a Android Bitmap class so that I can draw it onto a canvas element Its that simple. Thats all I want to do. Thats it. Nothing more. Nothing less. Sounds simple enough. So before you have a smirk on your face, read on further down.

I understand that this question has been asked a million times already. And I have also done my homework, researching it. Unfortunately I have hit a dead end from all sides. Maybe I need to make my question clear enough.

There is a limit on the amount of heap the Android VM lets you allocate. So loading a large bitmap, even the one from its own camera (I own a Nexus S) is not possible by using the following function.

BitmapFactory.decodeStream(InputStream is)

Yes I could scale it by using BitmapFactory.Options, but how then should I zoom in?

Now I am trying to design an image viewer which can smoothly zoom in/out from the image. Obviously that's not possible if I can't even load the image.

In gingerbread we have a new class BitmapRegionDecoder , but I am designing my app for Froyo. All these classes have hooks into the native api which use the Skia 2D Graphics Library. The Android NDK does not give access to these api's also. Maybe there is a way to manually build Skia and use it to load a java bitmap. But I am not sure how?

It seems to have been solved already (http://blog.javia.org/how-to-work-around-androids-24-mb-memory-limit/) in this app - https://market.android.com/details?id=image.viewer by using the memory allocated in the native C code using malloc/new. But I cant figure out how?

So make things clearer what I want is something that can zoom in/out of an image to full resolution. If possible it should be smooth or atleast it can be done in a separate thread.

If I need to use OpenGL, then please give me a sample code also.


Solution

  • I figured this out on my own. :)

    Its not the best way, but it works wonderfully.

    I created the bitmap in native code and accessed subset of its region using the Skia graphics library. (Which would mean that I am accessing private API's and its functionality could easily break with newer Android Versions).

    http://code.google.com/p/skia/

    I had to link against this lib in my C++ code and access this functionality through JNI.