1

我正在开发一个由许多图像作为精灵组成的 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(...)故意使用的,因为这种方法会在内部发生内存泄漏(如其他在线资源中所述)。

提前谢谢你,
兹拉特科

4

3 回答 3

1

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

另外我认为 createScaledBitmap() 泄漏的可能性很小。它所做的基本上就是你在这里所做的。

于 2011-05-28T00:39:19.923 回答
0

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

我建议你看看这个 Google I/O 会议:http ://www.youtube.com/watch?v=_CruQY55HOk

我认为您的问题只能通过降低位图的分辨率或使用某些缩放功能来解决,该功能不会实例化新的位图并修改现有的位图(如 AmandeepGrewal 提到的那个)。

于 2011-05-28T02:30:36.977 回答
0

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

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

于 2011-05-28T02:03:08.473 回答