【问题标题】:BitmapFactory.decodeFile causes outOfMemoryErrorBitmapFactory.decodeFile 导致 outOfMemoryError
【发布时间】:2014-01-15 22:02:33
【问题描述】:

BitmapFactory.decodeFile 仅当我从手机图库中选择图像时才会导致 outOfMemoryError,而不是当我从使用相机意图拍摄照片中选择图像时。在使用相机意图时,我实际上避免使用 decodeFile。从图库中选择(从意图中获取数据)时,我可以使用相同的方法吗?这是我以两种方式获取图像的代码:

如果图片是从设备的图库中选择的:

if (requestCode == 1) 
              {
                  if (intent != null && resultcode == RESULT_OK) 
                  {
                  ImageHelper ih = new ImageHelper();
                  mProfilePicPath = ih.getSelectedImageFilePathFromGallery(this, intent);
                  Bitmap portraitPhoto = ih.getChosenImageFromGallery(mProfilePicPath);
                    try{
                        ih.saveImage("Profile pics", portraitPhoto, this);

ImageHelper.getChosenImageFromGallery:

public Bitmap getChosenImageFromGallery(String imagePath) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imagePath, options);
        options.inSampleSize = DressingRoomActivity.calculateInSampleSize(options, 500, 500);
        options.inJustDecodeBounds = false;
        Bitmap portraitPhoto = ImageHelper.convertToPortraitOrientation(options, imagePath);
        return portraitPhoto;
    }

如果图像是通过使用相机拍照选择的:

else if ((requestCode == CAMERA_REQUEST)&& (resultcode == Activity.RESULT_OK)){
                Bundle extras = intent.getExtras();
                Uri selectedImage = intent.getData();
                if (extras != null) {
                    ImageHelper ih = new ImageHelper();
                    mProfilePicPath = ih.getFilePathFromCameraPhoto(this, selectedImage);
                    Bitmap photo = (Bitmap) intent.getExtras().get("data");
                    try{
                    ih.saveImage("Profile pics", photo, this);

如您所见,要从图库中获取图像并从中获取位图,我必须使用此代码 options.inSampleSize = DressingRoomActivity.calculateInSampleSize(options, 500, 500); 创建仅 500 x 500 像素的位图,否则会导致行上出现 outOfMemoryError @ 987654325@ 在ImageHelper.convertToPortraitOrientation(options, imagePath); 方法中。这意味着用户从相机中获得其图像的原样质量,并从他们在图库中的图像中获得 500 像素的质量。

我的问题:1) 从图库中选择时,有什么方法可以不让我的图像质量达到 500 像素?就像以某种方式避免这条线:Bitmap bmp = BitmapFactory.decodeFile(path, options); 或其他方式?

2) 对于画廊,我不得不将其转换为肖像,这只是一个小麻烦,但这是为什么呢?如果我不这样做,它会侧向翻转照片。

【问题讨论】:

    标签: android image bitmap out-of-memory


    【解决方案1】:

    Here 是官方文档中关于如何Display Bitmaps Efficiently 的完整教程。我和你有同样的问题。我所做的是在返回我的代码之前阅读并理解给定页面的所有课程。试试看,你的头脑会更清楚。

    编辑

    您的应用程序崩溃了,因为您正在主线程中运行Bitmap.decode() 方法。使用另一个线程(使用简单的AsyncTask)来执行此操作。

    正如我之前所说,有a nice tuto on how to handle bitmap off UI Thread

    【讨论】:

    • 读完之后,我认为这些方法中的大多数都是为了性能。我只是想暂时不要让内存崩溃。我认为唯一的解决方法是缩小我已经在做的图像:/它说缓存可以使用更多内存。它还建议不要使用 Wea​​kReference。不太确定该怎么做,因为我需要与输入质量相同的输出图像。这是一个照片编辑器应用程序。
    • 查看我的编辑。 I'm just looking at not crashing the memory for now :您必须很好地处理位图以避免应用程序崩溃。这就是为什么我提供上面的链接。阅读教程,尝试理解并回答任何问题。
    • 谢谢,但是从研究中我相当确定 asynctask 是为了使其加载更快,并且不会解决内存不足错误。它将在工作线程中占用相同的内存。我刚刚看过其他人的类似问题,答案始终是“使图像更小”。不幸的是,我认为这是我唯一的选择
    • 您将位图解码作业放在AsyncTask 中,以避免潜在的长时间运行的 I/O 作业(读取文件等),而不是将您从 OOM(分配)中解救出来。
    【解决方案2】:

    有两种可能的解决方案来克服 outOfMemory 异常:

    解决方案1:你应该使用weakReference变量,如。

    WeakReference<Bitmap> weakReferenceBitmap=new
                 WeakReference<Bitmap>(bitmap);
    

    GC 清除弱引用变量比其他变量更有效。

    解决方案2:您可以在清单中使用 largeHeap 属性来要求比正常情况更多的堆空间。

    <application
            android:largeHeap="true">
    
    </application>
    

    我不会向您推荐第二种解决方案,但它确实有效 :)

    希望它会有所帮助:)

    【讨论】:

    • 谢谢! largeHeap 听起来它可能无法在低质量的 Android 设备上使用。如果我编辑它,WeakReference 会在这种方法中工作吗? public static Bitmap createRotatedBitmap(Bitmap bm, float degree) { Bitmap bitmap = null; if (degree != 0) { Matrix matrix = new Matrix(); matrix.preRotate(degree); bitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true); } return bitmap; }
    • WeakRefrence 会起作用!但是如果你做了太多的解码,那么你应该使用 largeHeap 选项。别担心,应用也可以在低质量的安卓设备上运行。
    • 谢谢 :) 这个应用程序是关于图像的。有很多解码。所以我会使用 largeHeap。您认为我是否也应该使用 Wea​​lReference
    • 是的,请同时使用,因为 largeHeap 只是为了获得比正常更多的堆,但我们应该有效地管理该堆。
    • @user3164083 这就是为什么你不应该首先使用 largeHeap 作为解决 OOM 问题的方法:largeHeap pitfalls
    猜你喜欢
    • 1970-01-01
    • 2014-12-15
    • 1970-01-01
    • 2021-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多