4

I want to crop image of large size and tried using Bitmap.createBitmap but it gives OOM error. Also, tried multiple technique around createBitmap but none of them were successful.

Now I thinking of saving image to file system and crop it without loading image into memory that might solve the problem. But don't know how to do it.

User flow: User will take multiple pictures from in-app camera after each snap user can crop it manually or app will silently crop it on some predefine login and later it will send these images to server.

Can anybody guide me how I can achieve this?

user2095470
  • 356
  • 1
  • 6
  • 23
  • Well, one option would be to selectively copy certain bytes from the existing file into the new file. However, you'd need to understand the existing format and how to map that to the new file. – Chris Thompson Apr 25 '13 at 19:25
  • @chirs It is very abstract can you put some more light on your solution please. – user2095470 Apr 25 '13 at 20:17
  • I'd have to say that this is not possible but for the very most simple image formats. If you're dealing with JPEG or PNG images, you must, as far as I know, unpack them into bitmaps, select the portion you want and then generate a new image from that portion. – HonkyTonk Apr 25 '13 at 20:28
  • had a read here? http://stackoverflow.com/questions/11275650/how-to-increase-heap-size-of-an-android-application – sschrass Apr 25 '13 at 21:20
  • Are you really want to crop it (i.e. remove parts of the picture) or do you just want to shrink it to a smaller size? Shrinking can be done using various Bitmap... classes. – Ridcully Apr 26 '13 at 06:44
  • @Ridcully Yes, I want to crop them. – user2095470 Apr 26 '13 at 07:05

2 Answers2

3

There is a class called BitmapRegionDecoder which might help you, but it's available from API 10 and above.

If you can't use it :

Many image formats are compressed and therefore require some sort of loading into memory.

You will need to read about the best image format that fits your needs, and then read it by yourself, using only the memory that you need.

a little easier task would be to do it all in JNI, so that even though you will use a lot of memory, at least your app won't get into OOM so soon since it won't be constrained to the max heap size that is imposed on normal apps.

Of course, since android is open source, you can try to use the BitmapRegionDecoder and use it for any device.

android developer
  • 114,585
  • 152
  • 739
  • 1,270
0

I very much doubt you can solve this problem with the existing Android API.

What you need to do is obtain one of the available image access libraries (libpng is probably your best bet) and link it to your application via jni (see if there's a Java binding already available).

Use the low-level I/O operations to read the image a single scanline at a time. Discard any scanlines before or after the vertical cropped region. For those scanlines inside the vertical cropped region, take only those pixels inside the horizontal cropped region and write them out to the cropped image.

Edward Falk
  • 9,991
  • 11
  • 77
  • 112
  • To me it seems too much of effort and lot of chopping here and managing it across all the APIs (starting from 8) is daunting task. What about cropping at server end...and to user just show the the image and hide the part which will be later cropped by the server. – user2095470 Apr 26 '13 at 06:26
  • Cropping at the server would definitely be the way to go. By cropping at the server, you save immensely in bandwidth and load time. Plus, at the server end, it's simply a matter of installing the ImageMagick "convert" tool to do the cropping for you, and there's almost no code to write. – Edward Falk May 21 '13 at 23:41