Can't compress a recycled bitmap error

I've got a "Can't compress a recycled bitmap error" in my app. It happened on the picture.compress(Bitmap.CompressFormat.PNG, 90, fos); line in my code here:

    private void savePicture(byte[] data, String gameId, String folderName ) {
        File pictureFile = getOutputMediaFile(gameId, folderName);
        if (pictureFile == null){
            Log.error("Error creating media file, check storage permissions.");
            return;
        }

        Bitmap picture = BitmapFactory.decodeByteArray(data, 0, data.length);

        picture = getResizedBitmap(picture, bitmapWidth, bitmapHeight);

        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);

            picture.compress(Bitmap.CompressFormat.PNG, 90, fos);
            fos.close();
            picture.recycle();

            Log.info(">>> CameraActivity: PICTURE SAVED!");

        } catch (FileNotFoundException e) {
            Log.error(LibUtil.getStackTrace(e));
        } catch (IOException e) {
            Log.error(LibUtil.getStackTrace(e));
        }
    }

    public Bitmap getResizedBitmap(Bitmap bmp, int newWidth, int newHeight) {
        int width = bmp.getWidth();
        int height = bmp.getHeight();
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // CREATE A MATRIX FOR THE MANIPULATION
        Matrix matrix = new Matrix();
        // RESIZE THE BIT MAP
        matrix.postScale(scaleWidth, scaleHeight);

        // "RECREATE" THE NEW BITMAP
        Bitmap resizedBitmap = Bitmap.createBitmap(
                bmp, 0, 0, width, height, matrix, false);
        bmp.recycle();
        return resizedBitmap;
    }

What I find peculiar though is that when I commented the bmp.recycle(); line, the error is gone. It looks like (IMHO) the resizedBitmap and bmp are referencing the same bitmap. But I don't know whether it's the right thing to do and there's no memory leak or whatever in my app.

BTW, this code doesn't display the bitmap on any ImageView but it just take a picture from the camera periodically behind the scene and save it.

Thanks in advance.

Upvotes: 2

Views: 2728

Answers (3)

KyluAce
KyluAce

Reputation: 1000

Why you recycle the bitmap twice? You can't operate on the recycled one. I mean it can't be compressed, recycled again etc. Remove line bmp.recycle(); it is useless because you later recycle it in the try condition and like I said on the beginning you can't recycle an already recycled bitmap.

Upvotes: 0

Mohit Madaan
Mohit Madaan

Reputation: 469

Remove bmp.recycle(); from your getResizedBitmap method Because you are calling twice,so either get rid of recycle() or move it to after you have done everything that you intend to do with the Bitmap

Upvotes: 0

Blackbelt
Blackbelt

Reputation: 157457

the version of createBitmap doesn't always return a new Bitmap. In your case if resizedBitmap is equal to bmp, you are recycling both (same reference). In your getResizedBitmap add

 if (resizedBitamp != bmp) {
    bmp.recycle();
 }

But I don't know whether it's the right thing to do and there's no memory leak or whatever in my app.

unrelated to memory leaks.

Upvotes: 6

Related Questions