我正在开发一款由许多精灵图像组成的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(...)
,因为这种方法会在内部泄漏内存(如其他在线资源中所述)。
提前谢谢你,
兹拉特科
答案 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>