Rafael T
Rafael T

Reputation: 15679

display huge Images in Android

I'm intending to display very large Images in Android.

My first solution - to supply them as pdf - fails because not every handheld got a pdf-viewer preinstalled, and I don't want to require the users to install one.

So I have a png now (width = 3998px height=2827px) that I want to display. I downloaded this image to test how it would be displayed the gallery. It was quite painful. It seems that the galery renders this picture only once, and if I Zoom in, I cannot read the text at all.

So I wrote a testActivity which simply has an ImageView nested in a LinearLayout. I put the image into the drawable and set it as ImageView's image-source. Unforunately the app crashes immediatly, due to an "

 ERROR/AndroidRuntime(8906): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget"  

I didn't expect that ONE single Image can be too large forVM's memory. I played a little bit around, set ImageViews size to 3998 & 2827px , put the Image to sdCard and read it manually with a fileInputStream.
To my big surprise it now shows my image, but if I turn my Nexus S horizontal I get the same OutOfMemoryError as before.

Can somewone point me the main difference between recieving a Bitmap through a FileInputStream or to set it as ImageView's source.

Also I'm not able to scroll comfortable with two parent scrollViews

I searching for a simple solution to display ONE large image at a time with the ability to scroll horizontal and vertical while able to zoom in and out.

here is a sample of the image I want to display enter image description here

Upvotes: 29

Views: 39046

Answers (7)

Zikkoua
Zikkoua

Reputation: 806

Try to use this one: https://github.com/davemorrissey/subsampling-scale-image-view

A custom image view for Android, designed for photo galleries and displaying huge images (e.g. maps and building plans) without OutOfMemoryErrors. Includes pinch to zoom, panning, rotation and animation support, and allows easy extension so you can add your own overlays and touch event detection.

Upvotes: 7

hitesh141
hitesh141

Reputation: 943

We have to follow following steps to remove out of memory exception while loading huge images:

 1. Read Bitmap Dimensions and Type

 2. Load a Scaled down version into memory

Android Developer's Guide defines how we achieve these. here is the link

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html#load-bitmap

Upvotes: 1

M. Usman Khan
M. Usman Khan

Reputation: 4408

To handle scaling etc and using full resolution, You can use MapView of OSM (open street map) and provide it with your tiles (instead of the map). Check this: http://www.haakseth.com/?p=30

Upvotes: 1

M. Usman Khan
M. Usman Khan

Reputation: 4408

You can use this "easy to integerate" source of WorldMap application:

https://github.com/johnnylambada/WorldMap

This uses a huge image of a world map, and uses cache to display a map.

To integerate, I just copied all the java files (5 i guess) and used the surfaceView in my layout file. Then I went through the small OnCreate() method of ImageViewerActivity.java and used the code in my activity (with sligh alteration, depending on my personal use).

Upvotes: 4

FRR
FRR

Reputation: 71

I know its an old question but I used TileView to do exactly this:

https://github.com/moagrius/TileView

Upvotes: 7

leadersheep
leadersheep

Reputation: 328

I know it's an old post but I spent a lot of time on this problem, so here's my solution.

I wanted to display a 2000×3000 picture but I got out of memory or the image was too large to be displayed.

To begin, I get the dimensions of the picture:

o = new BitmapFactory.Options();
o.inJustDecodeBounds=true;
pictures = BitmapFactory.decodeStream(new FileInputStream(f), null, o);

Then I cut it up into four parts and displayed them with four ImageViews. I tried to load the full picture and cut it into four (using BitmapFactory.create(bitmap,int,int,int,int)) but got out of memory again.

So I decided to use some BitMapRegionDecoder:

for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
        ImageView iv = new ImageView(this);         
        InputStream istream =   null;
        try {
         istream = this.getContentResolver().openInputStream(Uri.fromFile(f));
        } catch (FileNotFoundException e1) {
         e1.printStackTrace();
        }
        BitmapRegionDecoder decoder     =   null;
        try {
        decoder = BitmapRegionDecoder.newInstance(istream, false);
        } catch (IOException e) {
                    e.printStackTrace();
        }
    int nw = (j*width/k);
    int nh = (i*height/k);

    Bitmap bMap = decoder.decodeRegion(new Rect(nw,nh, (nw+width/k),(nh+height/k)), null);    
    iv.setImageBitmap(bMap);

    }
}

This worked.

Upvotes: 30

Ben Lee
Ben Lee

Reputation: 3418

This post is a good demo for zooming a picture using multi touch gestures. It uses Matrix to zoom as well as pan a picture.

Upvotes: 2

Related Questions