Android BitmapFactory.decode文件导致outOfMemoryError

Android BitmapFactory.decode文件导致outOfMemoryError,android,image,bitmap,out-of-memory,Android,Image,Bitmap,Out Of Memory,BitmapFactory.decodeFile仅当我从手机多媒体资料中选择图像时才会导致outOfMemoryError,而不是当我从使用相机拍摄的照片中选择图像时才会导致outOfMemoryError。实际上,我在使用相机时避免使用decodeFile。当我从图库中选择(从意图中获取数据)时,是否可以使用相同的方法?以下是我用两种方式获取图像的代码: 如果从设备库中选择了图像: if (requestCode == 1) {

BitmapFactory.decodeFile仅当我从手机多媒体资料中选择图像时才会导致outOfMemoryError,而不是当我从使用相机拍摄的照片中选择图像时才会导致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);
如您所见,要从图库中获取图像并从中获取位图,我必须使用以下代码创建仅为500 x 500像素的位图
options.inSampleSize=DressingRoomActivity.calculateInSampleSize(选项,500500)否则它会在
Bitmap bmp=BitmapFactory.decodeFile(路径,选项)行上导致outOfMemoryError位于
ImageHelper.ConvertToPortRaitionation(选项,imagePath)中方法。这意味着用户从相机获得的图像质量为原样,从画廊中获得的图像质量为500px

我的问题:1)在从gallery中选择时,有没有办法不让我的图像质量达到500px?喜欢以某种方式避免这一行:
Bitmap bmp=BitmapFactory.decodeFile(路径,选项)或其他方式


2) 有了画廊,我不得不改成肖像画,这只是一个小麻烦,但为什么呢?如果我不这么做,它会把照片翻到一边

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

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

WeakReference<Bitmap> weakReferenceBitmap=new
             WeakReference<Bitmap>(bitmap);
WeakReference weakReferenceBitmap=new
WeakReference(位图);
GC clear weakReference变量与其他变量相比效率更高

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

<application
        android:largeHeap="true">

</application>

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

希望它能有所帮助:)

是一本关于如何从官方文件中下载的完整的图图。我和你有同样的问题。我所做的是在返回代码之前阅读并理解给定页面中的所有课程。试试看,你会把事情想得更清楚

编辑

你的应用程序正在崩溃,因为你正在主线程中运行
Bitmap.decode()
方法。使用另一个线程(使用简单的
AsyncTask
)来完成此任务


正如我之前所说,这里有

谢谢!largeHeap听起来可能无法在低质量的Android设备上使用。如果我编辑WeakReference,它在这个方法中会工作吗<代码>公共静态位图createRotatedBitmap(位图bm,浮点度数){Bitmap Bitmap=null;如果(度数!=0){Matrix Matrix=new Matrix();Matrix.preRotate(度数);Bitmap=Bitmap.createBitmap(bm,0,0,bm.getWidth(),bm.getHeight(),Matrix,true);}返回位图;}
WeakRefrence将起作用!但如果您正在做太多的解码,那么您应该使用largeHeap选项。别担心,这个应用程序也可以在低质量的android设备上运行。谢谢:)这个应用程序都是关于图像的。有很多解码。所以我将使用largeHeap。在您看来,我是否也应该使用WealReference?是的,请同时使用这两种方法,因为largeHeap只会获得比正常情况更多的堆,但我们应该有效地管理该堆。@user3164083这就是为什么您不应该将largeHeap作为解决OOM问题的第一种方法:在阅读了这篇文章之后,我认为大多数方法都是为了提高性能。我只是想暂时不要破坏记忆。我认为唯一的解决办法是缩小图像,我已经在做了:/它说缓存可以使用更多的内存。它还建议不要使用WeakReference。我真的不知道该怎么做,因为我需要一个与输入相同质量的输出图像。这是一个照片编辑器应用程序。请参阅我的编辑<代码>我只是想暂时不要破坏内存
:你必须很好地处理位图以避免应用程序崩溃。这就是我提供上述链接的原因。阅读短文,试着理解并回答任何问题。谢谢,但是我从研究中相当肯定asynctask是为了使其加载更快,并且不会解决outofmemoryerror。它将占用工作线程中相同的内存。我刚刚看过其他人提出的类似问题,答案始终是“缩小图像”。不幸的是,我认为这是我唯一的选择您将位图解码作业放入
AsyncTask
以避免潜在的长时间运行的I/O作业(读取文件等),而不是将您从OOM(分配)中解救出来。