Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recycled bitmap exception

Tags:

android

I'm getting this exception:

Exception: java.lang.IllegalStateException: Can't copy a recycled bitmap

My code is:

    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    int newWidth;
    int newHeight;
    if (width >= height) {
        newWidth = Math.min(width,1024);
        newHeight = (int) (((float)newWidth)*height/width);
    }
    else {
        newHeight = Math.min(height, 1024);
        newWidth = (int) (((float)newHeight)*width/height);
    }
    float scaleWidth = ((float)newWidth)/width;
    float scaleHeight = ((float)newHeight)/height;

    Matrix matrix = new Matrix();
    matrix.postScale(scaleWidth, scaleHeight);
    switch (orientation) {
    case 3:
        matrix.postRotate(180);
        break;
    case 6:
        matrix.postRotate(90);
        break;
    case 8:
        matrix.postRotate(270);
        break;
    }
    Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
    bitmap.recycle();
    try {
        bitmap = resizedBitmap.copy(resizedBitmap.getConfig(), true);
    }
    catch (Exception e) {
        Log.v(TAG,"Exception: "+e);
    }

If the exception is telling me that I've recycled resizedBitmap, that is patently false! What am I doing wrong??

like image 427
Richard Eng Avatar asked Jan 30 '12 22:01

Richard Eng


2 Answers

You are actually calling bitmap.recycle(); after this line:

Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
like image 111
bschultz Avatar answered Oct 16 '22 15:10

bschultz


Quote from Bitmap.createBitmap() method's Javadoc:

Returns an immutable bitmap from subset of the source bitmap, transformed by the optional matrix. The new bitmap may be the same object as source, or a copy may have been made. It is initialized with the same density as the original bitmap. If the source bitmap is immutable and the requested subset is the same as the source bitmap itself, then the source bitmap is returned and no new bitmap is created.

That mean that in some cases, i.e. when asking to resize a source bitmap to its actual size, there will be no difference between source and resized bitmap. To save memory the method will just return the same instance of bitmap.

To fix your code you should check whether a new bitmap has been created:

Bitmap resizedBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, width, height, matrix, true);
if (resizedBitmap != sourceBitmap) {
    sourceBitmap.recycle();
}
like image 30
xsveda Avatar answered Oct 16 '22 14:10

xsveda