2016-01-23 67 views
1

在我的項目中,我需要操作一個位圖並保存它。Android:修改並保存位圖,如何避免OOM?

要操縱我申請一個矩陣圖像,像這樣:

Bitmap b = Bitmap.createBitmap(((BitmapDrawable) imageView.getDrawable()).getBitmap(), 0, 0,width, height, matrix, true); 

我保存它是這樣的:

b.compress(Bitmap.CompressFormat.JPEG, 100, out); 

的問題是,如果這樣做,我可以得到一個OOM錯誤如果位圖很大。

任何建議如何避免它?

不幸的是縮小位圖並不是一個可接受的解決方案,因爲我需要保留位圖質量。

回答

1

我也有一些OOM與位圖,特別是在舊的(三星)設備。您可以使用一種簡單的方法捕捉OOM,啓動GC並重試。如果再次失敗,則可以(例如)向用戶顯示錯誤消息。

private void compressBitmap(/* args */) { 
    Bitmap b = Bitmap.createBitmap(((BitmapDrawable) imageView.getDrawable()).getBitmap(), 0, 0,width, height, matrix, true); 
    b.compress(Bitmap.CompressFormat.JPEG, 100, out); 
} 

try { 
    compressBitmap(/* args */); 
} catch(OutOfMemoryError e) { 
    System.gc(); 
    // try again 
    try { 
     compressBitmap(/* args */); 
    } catch(OutOfMemoryError e) { 
     System.gc(); 
     // Inform user about the error. It's better than the app crashing 
    } 
} 

但這只是一種解決方法。如果你真的想在這種情況下有效地防止OOM,我認爲你必須使用NDK。無論如何,它比應用程序崩潰要好。

+0

本地好的建議 –

+0

要點是:即使是本地人,如何防止OOM?無論如何,我們需要在內存中加載位圖,不是嗎?如果我們在內存中加載位圖,我們甚至會使用本地方法來獲得OOM,對吧? –

+0

我不熟悉本地化,但據我所知,與NDK分配內存不計入Java堆,[請參閱此處的問題/答案](http://stackoverflow.com/questions/21520110/)機器人-NDK-達爾維克堆和天然-堆如何-分離最兩者之間-)。因此,如果你在那裏加載和操作你的位圖,它不應該導致任何OOM。 – patloew