2011-05-28 32 views
1

我正在开发包含许多图像为精灵的Android游戏。在Android中缩放图像会导致OutOfMemory异常

当我加载图像的方式如下:

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 

为什么结垢造成内存溢出的例外?我甚至尝试回收原始图像以节省一些空间。我没有故意使用Bitmap.createScaledBitmap(...),因为此方法会在内部泄漏内存(如其他在线资源中所述)。

谢谢你在前进,
兹拉特科

回答

1

你可能只是非常接近的内存限制。它看起来像你正在创造一个很大的位图(我不知道为什么你使它与原始位图相同的大小)。从日志中,你已经使用了25MB的Java分配和18MB的位图分配,所以你基本上正确地对抗了48MB堆的限制。

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

+0

为什么第一个代码片段永远不会导致OOM异常?事实上,在第二个片段中,我将原始位图缩放到其大小的80%。分配,有2.5MB,而不是25MB – Bart 2011-05-28 00:54:33

0

您应该尝试在BitmapFactory.Options类中使用变量“inSampleSized”。这将扩展而不使用多余的内存。

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

+0

“inSampleSize”是一个int变量> = 1,因此我无法精确控制缩放因子。游戏需要特定的上调和下调比例因子e.x. 0.7688 – Bart 2011-05-28 21:01:11

+0

调整大小时是否需要保存位图?为什么不在绘制位图时在画布上应用矩阵。较大的位图将存储在内存中,但可能会使用较少的内存,因为不需要分配另一个位图。 – 2011-05-30 14:19:55

0

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

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

我认为你的问题只能通过打倒你的位图的分辨率或通过使用一些尺度函数来解决,那并不没有实例化一个新的位图并修改现有的(如AmandeepGrewal提到的那个)。

+0

感谢您的链接。这真的是教育。至于这个问题,我不能降低解决方案,因为它应该被严格定义。另外,我尝试了缓存所有已经加载的资源的解决方案。当我不是图像回收时,我最终会收到OutOfMemory。当我回收时,然后我得到SIGNAL 11(WIN_DEATH)本地错误很难调试。它变得非常令人沮丧...... – Bart 2011-05-28 21:06:00

相关问题