1

I continuously get OutOfMemory exceptions trying to decode an image from camera in my Android app. There are many questions dealing with the problem, but my case is especially weird because I get the exception even when just trying to get the bounds with options.inJustDecodeBounds=true.

Here's the code that starts the camera:

protected void takePicture() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    File image = new File(IMAGE_PATH, "camera.jpg");
    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image));
    startActivityForResult(takePictureIntent, 0);
}

Here's the code that triggers the exception:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK ) { 
        String rawImageName = new String(IMAGE_PATH + "/camera.jpg");

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(rawImageName); // The exception is thrown here
            .
            .
            .
    }
}

I tried to decode the image using a very high sampling rate, but still I get the same exception:

options.inSampleSize = 20;
options.inJustDecodeBounds = false;
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap photo = BitmapFactory.decodeFile(rawImageName); // Again the exception

Except for that, the application seems to run correctly and there is enough free memory. I can open correctly the image in the gallery app. Moving the image to a different directory didn't help. Any ideas what could cause it? What could possibly cause the exception while decoding with inJustDecodeBounds = true?

FireAphis
  • 6,650
  • 8
  • 42
  • 63

2 Answers2

10

You need to pass the options to the decode call:

BitmapFactory.decodeFile(rawImageName, options);
Henry
  • 42,982
  • 7
  • 68
  • 84
  • 1
    Oh, my stupidity!!! That's what happens when you copy-paste your code. Grrr hours of pulling my hair out!!! – FireAphis Jan 15 '13 at 10:12
2
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = 4; // 1/4
o2.inPurgeable = true;
Bitmap b=BitmapFactory.decodeFile(imagePath,o2);

try this. and also resize your image and make bitmap objects null after use. give call to System.gc(); it doesn call gc but it gives hint. also dont make lots of bitmap objects. reuse the same bitmap object and make it null after use.

Siddhesh
  • 1,370
  • 11
  • 28
  • Rather use recycle() on the bitmap instead of gc. GC might not free up the memory immediately. See http://mobi-solutions.blogspot.com/2010/08/how-to-if-you-want-to-create-and.html and http://stackoverflow.com/questions/3823799/android-bitmap-recycle-how-does-it-work – Chris Aug 27 '14 at 08:48
  • 1
    Yes you are right. If you are no more using bitmap objects recycle them. – Siddhesh Aug 27 '14 at 08:50
  • Calling System.gc() is really an anti-pattern that should be avoided. You can find a lot of documentation about this online. To summarize, it screams "broken code", it's not guaranteed to do anything and it might slow your code down, because you might start a full GC cycle. Always avoid System.gc(). – Erik Duindam Mar 07 '16 at 02:40