Rotating bitmap causes outOfMemoryException

2019-02-13 13:12发布

I am rotating a bitmap this way, on every button click the image rotates 90 degrees

Matrix matrix = new Matrix();
matrix.postRotate(90);
rotated = Bitmap.createBitmap(rotated, 0, 0,
        rotated.getWidth(), rotated.getHeight(), matrix, true);
iv.setImageBitmap(rotated);

I tried this with a lot of images, but now one caused an OutOfMemoryError. Is there a way to prevent this? Of course I can call recycle, but then I lose the bitmap and have to get it again from the imageview. I don't think that will make any difference.

3条回答
唯我独甜
2楼-- · 2019-02-13 13:30

Try Like Below:

Matrix matrix = new Matrix();
matrix.postRotate(90);
rotated = Bitmap.createBitmap(rotated, 0, 0,rotated.getWidth(), rotated.getHeight(), matrix, true);
ByteArrayOutputStream bmpStream = new ByteArrayOutputStream();
rotated.compress(Bitmap.CompressFormat.JPEG,100, bmpStream);
iv.setImageBitmap(rotated);
查看更多
别忘想泡老子
3楼-- · 2019-02-13 13:40

I have suggestions for you.

1) When you have any memory hunger task, use in methods and if possible with AsyncTask.
2) Declare objects as WeakReference. This will give you chance to release memory after use. See below example.

public class RotateTask extends AsyncTask<Void, Void, Bitmap> {
    private WeakReference<ImageView> imgInputView;
    private WeakReference<Bitmap> rotateBitmap;

    public RotateTask(ImageView imgInputView){
        this.imgInputView = new WeakReference<ImageView>(imgInputView);
    }

    @Override
    protected void onPreExecute() {
        //if you want to show progress dialog
    }

    @Override
    protected Bitmap doInBackground(Void... params) {
        Matrix matrix = new Matrix();
        matrix.postRotate(90);
        rotateBitmap = new WeakReference<Bitmap>(Bitmap.createBitmap(rotated, 0, 0,rotated.getWidth(), rotated.getHeight(), matrix, true));
        return rotateBitmap.get();
    }

    @Override
    protected void onPostExecute(Bitmap result) {
        //dismiss progress dialog
        imgInputView.get().setImageBitmap(result);
    }
}

This task has all the views and object as WeakReference. When this task is completed, all the memory used by this Task is free. Try this approach. I used in my application.

查看更多
倾城 Initia
4楼-- · 2019-02-13 13:46

If you need to just view the images, you can set a rotate drawable as shown here

If you care about real rotation of the bitmap, and you also want to avoid OOM, check this link

查看更多
登录 后发表回答