0

after googling a lot I have not yet found a way to resize an image preserving quality.

I have my image - stored by camera in full resolution - in

String filePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/my_directory/my_file_name.jpg";

Now, I need to resize it preserving aspect ratio and then save to another path.

What's the best way to do this without occurring the error "Out of memory on a xxxxxxx-byte allocation."?

I continue to retrieve this error on Samsung devices, I tried in every way, even with the library Picasso.

Thanks!

shaithana
  • 2,470
  • 1
  • 24
  • 37
  • 1
    Technically speaking, downsizing a raster image will always reduce quality, since there are fewer pixels to store data in. – Jave Oct 04 '14 at 18:33

1 Answers1

0

1st things 1st: depending on device and bitmap size, no matter what magic code you do, it will crash! Specially cheap Samsung phones that usually have no more than 16mb of RAM to the VM.

You can use this code How to get current memory usage in android? to check on amount of memory available and deal with it properly.

When doing those calculations, remember that bitmaps are uncompressed images, that means, even thou the JPG might be 100kb, the Bitmap might take several MB.

You'll use the code shown here https://developer.android.com/training/displaying-bitmaps/load-bitmap.html to read the bitmap boundaries, and do an approximate scale down as close as possible to the size you actually need, or enough to make the device not crash. That's why it's important to properly measure the memory.

That 1st code takes virtually no RAM as it creates from the disk, making it smaller by simply skipping pixels from the image. That's why it's approximate, it only does in power of 2 the scaling.

Then you'll use the standard API to scale down to the size you actually need https://developer.android.com/reference/android/graphics/Bitmap.html#createScaledBitmap(android.graphics.Bitmap, int, int, boolean)

so the pseudo code for it, will be:

try{
    Info info = getImageInfo(File);
    int power2scale = calculateScale(info, w, h);
    Bitmap smaller = preScaleFromDisk(File, power2scale);
    Bitmap bitmap = Bitmap.createScaledBitmap(smaller, w, h, f);
} catch(OutOfMemoryError ooe){
    // call GC
    // sleep to let GC run
    // try again with higher power2scale
}
Community
  • 1
  • 1
Budius
  • 39,391
  • 16
  • 102
  • 144