Search code examples
androidandroid-cameraout-of-memoryandroid-gallery

Bitmap - Out of memory exception


When I try to get image from camera or gallery, I get error. Here is a part of logcat:

06-27 05:51:47.297: E/dalvikvm-heap(438): Out of memory on a 35295376-byte allocation.
06-27 05:51:47.312: E/dalvikvm(438): Out of memory: Heap Size=108067KB, Allocated=71442KB, Limit=131072KB
06-27 05:51:47.312: E/dalvikvm(438): Extra info: Footprint=108067KB, Allowed Footprint=108067KB, Trimmed=56296KB
06-27 05:51:47.312: E/PowerManagerService(438): Excessive delay when setting lcd brightness: mLcdLight.setBrightness(176, 1) spend 288ms, mask=2
06-27 05:51:48.052: E/dalvikvm-heap(4332): Out of memory on a 24023056-byte allocation.
06-27 05:51:48.057: E/dalvikvm(4332): Out of memory: Heap Size=63139KB, Allocated=40922KB, Limit=65536KB
06-27 05:51:48.057: E/dalvikvm(4332): Extra info: Footprint=63139KB, Allowed Footprint=63139KB, Trimmed=0KB
06-27 05:51:48.057: E/EmbeddedLogger(438): App crashed! Process: <my_app_name>

Here is my code that provides me to take an image:

Intent pickIntent = new Intent();
pickIntent.setType("image/*");
pickIntent.setAction(Intent.ACTION_GET_CONTENT);

Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

Intent chooserIntent = Intent.createChooser(pickIntent, "Select or take a new Picture");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { takePhotoIntent });
startActivityForResult(chooserIntent, selectPic);

and at onActivityResult() I do:

Bitmap bitmapSelectedImage = null;
Uri selectedImage =  data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };

Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();

String filePath = cursor.getString(cursor.getColumnIndex(filePathColumn[0]));
cursor.close();
bitmapSelectedImage = BitmapFactory.decodeFile(filePath); // Here is where do I get error.

I get error on bitmapSelectedImage = BitmapFactory.decodeFile(filePath); line.

I have looked a lot websites/topics for it but no one could helped.

Any suggestions?


Solution

  • your memory allocation heap size is something very limited. trying loading high resolution image from file to the heap can easily cause out of memory error.

    assuming that the camera app really taking a very high resolution (almost sure that is the case), you should load to memory only scaled version of the bitmap in the size required for displaying.

    the document you already been suggested to see - http://developer.android.com/training/displaying-bitmaps/load-bitmap.html provides full functionall methods to do exactly that.

    1) first step is calculating (without loading to memory) the required scale. that's the calculateInSampleSize method.

    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
    
        if (height > reqHeight || width > reqWidth) {
    
            // Calculate ratios of height and width to requested height and
            // width
            final int heightRatio = Math.round((float)height / (float)reqHeight);
            final int widthRatio = Math.round((float)width / (float)reqWidth);
    
            // Choose the smallest ratio as inSampleSize value, this will
            // guarantee
            // a final image with both dimensions smaller than or equal to the
            // requested height and width.
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
    
        return inSampleSize;
    }
    

    2) second step is the full method using step 1:

    public static Bitmap getSampleBitmapFromFile(String bitmapFilePath, int reqWidth, int reqHeight) {
        // calculating image size
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(new File(bitmapFilePath)), null, options);
    
        int scale = calculateInSampleSize(options, reqWidth, reqHeight);
    
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
    
        return BitmapFactory.decodeStream(new FileInputStream(new File(bitmapFilePath)), null, o2);
    
    }
    

    reqHeight and reqWith are the hight and width in pixels of the image view that displaying the image. so let's say your image view is 100x100 pixels, all you need to do is:

    bitmapSelectedImage = getSampleBitmapFromFile(filePath, 100, 100);