2011-05-28 30 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

相關問題