8

I am working in a map project in android. It contains larger image of 10000x10000 resolution. Using this image with Bitmap it gives OutOfMemoryError. So I want to tile and scroll this image. When I scroll image, only visible screen must have tiles and other invisible tiles must be recycled. I spent lots of time but didn't find anything.

Any help will be appreciated. Provide me better solutions or idea.

ismail
  • 46,010
  • 9
  • 86
  • 95
ankita gahoi
  • 1,532
  • 2
  • 15
  • 28
  • Are you looking for some open source program which does this? Or are you just interested in algorithm? – Greg Dan Jan 13 '11 at 09:17
  • hello greg, Any of one will work for me. – ankita gahoi Jan 13 '11 at 09:23
  • Related question: http://stackoverflow.com/questions/3058164/android-scrolling-an-imageview – rds Nov 01 '12 at 13:10
  • @ankitagahoi : i am facing the same issue like you right now. I have used the custom view and Ract to draw. But i could not see the image on the device. I can see the full image and canvas on blue stack but when i install in device it wont work. May i know how it works in device – Arpit Patel Feb 19 '13 at 06:46

4 Answers4

5

Starting from API level 10, you can use BitmapRegionDecoder to load specific regions from an image without the need of manually generating the tile images. I've recently developed a lib that provides the visualisation of large images with touch gesture handling. The source code and samples are available at https://github.com/diegocarloslima/ByakuGallery

diegocarloslima
  • 1,346
  • 14
  • 16
5

as per Dave's recommendation, you can split the image into 1600 parts of 250x250px each. Photoshop does this easily in less than a minute (here). You don't have to worry about writing the html yourself too. Once you have the html (lets call it bigimage.html) and the images folder, place both these in your assets folder and access them this way -

    setContentView(webView);
    try {
        webView.loadUrl("file:///android_asset/bigimage.html";
        webView.getSettings().setLoadsImagesAutomatically(true);
    } catch (Exception e) {
        e.printStackTrace();
    }
Mukul Jain
  • 1,807
  • 9
  • 26
  • 38
4

Someone I know ran into the same problem. They solved it by first splitting the image into square tiles. Then they generate an HTML page that displays the images in a <table> layout and get the built-in browser to display the resulting page. This means the browser manages the visibility of the images, and it gives you bi-directional scrolling and pinch-to-zoom.

This approach is very easy to code, but loses the flexibility of writing your own custom solution. This was for a smaller image (2000x1500 ish) so I'm not sure how it will scale to the dimensions you need.

If you do go this route, make sure you have border="0" cellpadding="0" cellspacing="0" on your table and border="0" on the images to ensure that the joins are seamless.

dave.c
  • 10,910
  • 5
  • 39
  • 62
  • hello dave.c actually this is offline application,I can not use browser.so plz provide me another solution. – ankita gahoi Jan 13 '11 at 12:44
  • This solution works offline, as your app creates the HTML on the fly in the phone, then gets the browser to display it. No network access required. You could probably also generate the HTML and use a `WebView` to show it. – dave.c Jan 13 '11 at 12:59
  • please let us know how you get on – dave.c Jan 14 '11 at 09:57
  • Is there anyway to use this method to create an `Overlay` for a Google Maps project? I've tried tiling it myself with a `BitmapRegionDecoder`, but the image seems to get corrupted. This approach interests me but I'm not sure if I can use HTML to create a transparent `Overlay` for a `MapView`. – Jason L Jun 18 '12 at 19:50
  • Any reason you need a ``? Would multiple `
    ` work as well?
    – izolate Apr 13 '13 at 22:28
  • @muppethead I would think that you could probably get a bunch of `
    `s that would achieve the same effect as a ``. Personally I'd find a table slightly easier to work with as there would be less css/styling involved.
    – dave.c Apr 15 '13 at 08:49
0

You could tile your image into square tiles (for example 256x256 px).

You can subclass View, and maintain current offset from the center [0,0] in member variables.

In onDraw(Canvas) you should draw the tiles which are visible based on the current offset (it's easy to calculate which should be visible as you know the current translation offset, size of each tile and size of the screen. Simply draw the tiles as Bitmaps onto the Canvas.

Then handle onTouchEvent in your Activity. You can handle MotionEvent.ACTION_MOVE where you'd only move around the currently visible tiles, and then on MotionEvent.ACTION_UP you'd do a real repaint and invoke a thread to fetch the new tiles (so you won't do an expensive operation on each finger movement). Use View's invalidate() method to force it to repaint after the panning.

Axarydax
  • 16,353
  • 21
  • 92
  • 151