6

I am working in an android application and I am using a bitmap to bind an image to an ImageView. My requirement is to rotate that ImageView and give a border to that ImageView. I have successfully implemented this, but after the application uses this activity two-three times a "force close" error appears saying Bitmap out of VM memory. Please help me to minimize the bitmap memory consumption in my code. And let me know how to modify the code for the same?

final int BORDER_WIDTH = 5;
        // Set the border color
        final int BORDER_COLOR = Color.WHITE;
        Bitmap res = Bitmap.createBitmap(CAPTURE_IMAGE.getWidth() + 2
                * BORDER_WIDTH, CAPTURE_IMAGE.getHeight() + 2 * BORDER_WIDTH,
                CAPTURE_IMAGE.getConfig());
        System.gc();
        Canvas canvas = new Canvas(res);
        Paint paint = new Paint();
        paint.setColor(BORDER_COLOR);
        canvas.drawRect(0, 0, res.getWidth(), res.getHeight(), paint);

        canvas.drawBitmap(CAPTURE_IMAGE, BORDER_WIDTH, BORDER_WIDTH, paint);
        Matrix mat = new Matrix();
        // Set the Imageview position
        mat.postRotate(355);

        bMapRotate = Bitmap.createBitmap(res, 0, 0, res.getWidth(),
                res.getHeight(), mat, true);
        System.gc();
        res.recycle();
        res = null;
        paint = null;
        canvas = null;
        mat = null;
        // Set the captured bitmap image in the imageview
        mShareImageView.setImageBitmap(bMapRotate);
Jigar Pandya
  • 6,004
  • 2
  • 27
  • 45
Arun PS
  • 4,610
  • 6
  • 41
  • 56
  • 1
    i've created a nice JNI solution that avoids out-of-memory by removing the max heap size limitation barrier . [**here's a link**](http://stackoverflow.com/questions/14398670/android-rotating-a-bitmap-using-jni-ndk#comment20033361_14398670) to my snippet. some notes: - replace in the code every instance of "uint16_t" with "uint32_t" (that's the bug on my code i've asked about) . - input and output bitmap must be with 8888 config (which is ARGB ) - input bitmap will be recycled during the process . - the code rotates the image 90 degress counter clock wise . of course you can change it depending – android developer Jan 18 '13 at 13:18

4 Answers4

3

I think you should use shrink function like this

bMapRotate = Bitmap.createBitmap(res, 0, 0, res.getWidth(),
                res.getHeight(), mat, true);


Bitmap myBitmap = ShrinkBitmap(bMapRotate , 300, 300);

mShareImageView.setImageBitmap(myBitmap );


private Bitmap ShrinkBitmap(String file, int width, int height) {
        // TODO Auto-generated method stub
        BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
        bmpFactoryOptions.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);

        int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
        int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);

        if (heightRatio > 1 || widthRatio > 1)
        {
         if (heightRatio > widthRatio)
         {
          bmpFactoryOptions.inSampleSize = heightRatio;
         } else {
          bmpFactoryOptions.inSampleSize = widthRatio;
         }
        }

        bmpFactoryOptions.inJustDecodeBounds = false;
        bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);
     return bitmap;
    }

it worked for me and i avoided Bitmap out of VM memory exception

Avi Kumar
  • 4,403
  • 8
  • 36
  • 67
3

in mainfest file add ---> android:largeHeap:"true"

ajay
  • 477
  • 6
  • 14
  • Just a note for others: I tried putting this in my `` tags in the manifest, the one causing the errors, and it didn't work. But when I put it in the `` tags it worked. Also, should be `android:largeHeap="true"`. Only use one colon. – Azurespot Apr 06 '15 at 06:18
1

Try moving the gc() call to the end. It should run after you set res = null so that it can release the unused memory:

    res.recycle();
    res = null;
    paint = null;
    canvas = null;
    mat = null;
    System.gc();
Caner
  • 57,267
  • 35
  • 174
  • 180
0

Just add android:largeHeap="true" in your manifest file

Ref: largeHeap=true manifest tag not working?

Mayura
  • 91
  • 1
  • 1