在Android中缩放图像会导致OutOfMemory异常

时间:2011-05-28 00:18:24

标签: android bitmap out-of-memory image-scaling recycle

我正在开发一款由许多精灵图像组成的Android游戏。

当我按以下方式加载图像时:

public static Bitmap loadBitmap(int resId) {  
    return BitmapFactory.decodeResource(getResources(), resId, options);
}

一切都很好。

当我尝试使用此代码缩小或放大位图时:

public static Bitmap loadBitmap(int resId) {
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId, options);
    Matrix matrix = new Matrix();
    matrix.postScale(0.8f, 0.8f);
    Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    bitmap.recycle();
    bitmap = null;
    return scaledBitmap;
}

应用程序崩溃时出现以下异常:

2211840-byte external allocation too large for this process.  
Out of memory: Heap Size=4935KB, Allocated=2549KB, Bitmap Size=18463KB  
VM won't let us allocate 2211840 bytes

为什么缩放导致OutOfMemory异常?我甚至尝试回收原始图像以节省一些空间。我没有故意使用Bitmap.createScaledBitmap(...),因为这种方法会在内部泄漏内存(如其他在线资源中所述)。

提前谢谢你,
兹拉特科

3 个答案:

答案 0 :(得分:1)

你可能只是非常接近内存限制。看起来你正在创建一个非常大的位图(我不确定你为什么要使它与原始位图的大小相同)。从日志中,您使用了25MB的Java分配和18MB的位图分配,因此您基本上可以抵御48MB的堆限制。

另外我认为createScaledBitmap()不太可能泄漏。它所做的一切基本上就是你在这里所做的。

答案 1 :(得分:0)

您应该尝试在BitmapFactory.Options类中使用变量“inSampleSized”。这将在不使用过多内存的情况下进行扩展。

http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize

答案 2 :(得分:0)

我猜你真的很接近堆限制。在你的函数中,你基本上是在实例化第二个Bitmap,这大致会导致内存翻倍(Bitmaps非常大)。如果您使用的是早于Honeycomb的操作系统,那么查看内存值也会产生误导,这些内存值会在某处打印出来。 iirc,Bitmaps直接保存在系统内存堆上,而其他所有内容都保存在vm堆上(这些是你看到的值 - > 2.5MB)。但是,Bitmap分配的内存也会计入内存堆限制。 :/

我建议您查看此Google I / O会话:http://www.youtube.com/watch?v=_CruQY55HOk

我认为你的问题只能通过降低你的Bitmap的分辨率或使用一些比例函数来解决,它不会实例化一个新的Bitmap并修改现有的Bitmap(就像AmandeepGrewal提到的那个)。 p>

相关问题