2

I was trying to fix the issue of Android Camera Intent Saving Image Landscape When Taken Portrait, but ran into the issue of an dalvikvm-heap Out of memory on a 63489040-byte allocation. error. I looked at createBitmap() leads me into a java.lang.OutOfMemoryError, but that question was not of any help. I'm not sure how to fix this. I tried calling recycle()on the bitmap, but that didn't work.

String file = getRealPathFromURI(Uri.parse(mUriString));
BitmapFactory.Options bounds = new BitmapFactory.Options();
bounds.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file, bounds);

BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFile(file, opts);
ExifInterface exif = new ExifInterface(file);
String orientString = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
int orientation = orientString != null ? Integer.parseInt(orientString) : ExifInterface.ORIENTATION_NORMAL;
int rotationAngle = 0;

switch(orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
    rotationAngle = 90;
case ExifInterface.ORIENTATION_ROTATE_180:
    rotationAngle = 180;
case ExifInterface.ORIENTATION_ROTATE_270:
    rotationAngle = 270;
}

Matrix matrix = new Matrix();
matrix.setRotate(rotationAngle, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
Bitmap rotatedBitmap = Bitmap.createBitmap(bm, 0, 0, bounds.outWidth, bounds.outHeight, matrix, true);
bm.recycle();

This code reads the EXIF data and orientates the image properly.

I should also add that I am compressing the image here:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageBytes = baos.toByteArray();
rotatedBitmap.recycle();
baos.close();
Community
  • 1
  • 1
lschlessinger
  • 1,934
  • 3
  • 25
  • 47

2 Answers2

18

You can reduce the memory when you decode the image in your BitmapFactory.Options through skipping ARGB_8888 and using RGB_565 instead. and inDither to true to preserve image quality.

sample:

BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = false;
opts.inPreferredConfig = Config.RGB_565;
opts.inDither = true;
Rod_Algonquin
  • 26,074
  • 6
  • 52
  • 63
3

you could use opts.inSampleSize = 2 or above to avoid the OOM exception.

Kosh
  • 6,140
  • 3
  • 36
  • 67