6

From experiments and from reading other posts like this one it seems that it's hard to process high resolution images on Android because there is a limit on how much memory the VM will allow to allocate.

Loading a 8MP camera pictures takes around 20 MB of memory.

I understand that the easy solution is to downsample the image when loading it (BitmapFactory offers such an option) but I still would like to process the image in full resolution: the camera shoots 8MP, why would I only use 4MP and reduce the quality.

Does anyone know good workarounds for that?

Community
  • 1
  • 1
Kamchatka
  • 3,597
  • 4
  • 38
  • 69

3 Answers3

2

In a resource-constrained environment I think that your only solution is to divide and conquer: e.g. caching/tiling (as in: tiles)

Instead of loading and processing the image all at once you load/save manageable chunks of the image from a raw data file to do your processing. This is not trivial and could get really complex depending on the type of processing you want to do, but it's the only way if you don't want to comprise on image quality.

Paul Sasik
  • 79,492
  • 20
  • 149
  • 189
  • I thought about tiling. It makes the image processing a bit more complicated but the main drawback is that at the end I need to reconstruct the final file which would be from a lot of temporary file. That's probably doable but very heavy. – Kamchatka Dec 29 '11 at 00:13
  • If your image's dimensions don't change during the processing then you would not need temp files. You could write processed sections/tiles of into the proper sections of the image file. – Paul Sasik Dec 29 '11 at 01:56
  • Right. I'm afraid of really bad processing time with all the IOs. Any idea how much slower it is to write to flash memory compared to the phone RAM? – Kamchatka Dec 29 '11 at 15:29
2

Indeed, this is hard. But in case image is in some continuous raster format, you can mmap it ( see java.nio.ByteBuffer ) - this way you get byte buffer without allocating it.

Konstantin Pribluda
  • 12,329
  • 1
  • 30
  • 35
1

2 things:

  1. Checkout the gallery in Honeycomb. It does this tiled based rendering. You can zoom in on an image and you see then that the current part is higher res then the other parts. If you pan around you see it rendering.

  2. When using native code (NDK) there is not a resource limit. So you could try to load all the data native and somehow get parts of it using JNI, but I doubt it's better then the gallery of honeycom.

Peterdk
  • 15,625
  • 20
  • 101
  • 140
  • Regarding 1. the BitmapFactory is indeed designed to do stuff like that: loading a region only, loading in lower resolution. Loading regions could be helpful to achieve tiling like @paul-sasik suggests. – Kamchatka Dec 29 '11 at 00:15
  • Regarding 2. the same limits apply to native code. I get myself with native OutOfMemory errors rendering things. – Marcos Vasconcelos May 25 '12 at 14:45