如何处理大型位图。旋转和插入到相册中。

5

我需要使用相机拍照,并在将其保存到图库之前根据图片大小旋转它。

我正在使用以下方法:

Intent imageCaptureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); imageCaptureIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); startActivityForResult(imageCaptureIntent, IMAGE_CAPTURE);

用于拍照并将其保存到临时文件中。

然后是

Bitmap bmp = BitmapFactory.decodeFile(imagePath);
String str = android.provider.MediaStore.Images.Media.insertImage(cr, bmp, name, description);

用于保存它。

这是我尝试使用的代码来旋转位图:

Matrix matrix = new Matrix();
matrix.postRotate(180);
Bitmap x = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
android.provider.MediaStore.Images.Media.insertImage(cr, x, name, description);

问题是我得到了一个OutOfMemoryException。

有什么更好的方法来处理位图,以避免内存破裂吗?

提前感谢您的帮助,祝好!

2个回答

2

我认为没有更好的处理位图的方式了。你可以尝试逐部分直接从文件中解析数据作为Byte[],并对其进行操作; 这很困难,你可能最终会得到非常丑陋的代码。

我还建议以下几点:

  • 使用android.provider.MediaStore.Images.Media.insertImage(cr, imagePath, name, description)而不是android.provider.MediaStore.Images.Media.insertImage(cr, bmp, name, description)这样就不需要调用Bitmap bmp = BitmapFactory.decodeFile(imagePath),也不会在那个时候加载任何位图到内存中。

  • 在整个代码中,确保只有在需要时才加载位图。将不再需要的位图设置为null并调用垃圾收集器,或使用bmp.recycle()


bmp.recycle()在这里没有帮助,因为你实际上可以在捕获OOM之后立即正确地执行它。我的意思是,在旋转位图并保存它之后。然而,OOM很可能在旋转时出现,因为它必须在RAM中保留2个相同的位图。 - Stan

0

我在旋转位图方面遇到了同样的问题。问题在于:

    Bitmap bmp = BitmapFactory.decodeFile(imagePath); //this is the image you want to rotate
    // keeping in mind that you want to rotate the whole original image instead
    // of its downscaled copy you cant use BitmapFactory downscaling ratio
    Matrix matrix = new Matrix();
    matrix.postRotate(180);
    Bitmap x = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true); 
    // the line above creates another bitmap so we have here 2 same sized bitmaps
    // even using the same var (bmp instead of x) wont change anything here
    // so you gonna get the OOM here

这是因为它创建了2个位图,所以他们需要多x2的RAM。
请查看我的问题和解决方案。我打赌是ImageMagick库。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接