6

我正在android應用程序中工作,我正在使用位圖將圖像綁定到ImageView。我的要求是旋轉該ImageView並給該ImageView一個邊框。我已經成功實現了這一點,但是在應用程序使用此活動後,出現兩次「強制關閉」錯誤,表示位圖從VM內存中移出。請幫我減少我的代碼中的位圖內存消耗。並讓我知道如何修改相同的代碼?Android中的位圖內存不足錯誤...

final int BORDER_WIDTH = 5; 
     // Set the border color 
     final int BORDER_COLOR = Color.WHITE; 
     Bitmap res = Bitmap.createBitmap(CAPTURE_IMAGE.getWidth() + 2 
       * BORDER_WIDTH, CAPTURE_IMAGE.getHeight() + 2 * BORDER_WIDTH, 
       CAPTURE_IMAGE.getConfig()); 
     System.gc(); 
     Canvas canvas = new Canvas(res); 
     Paint paint = new Paint(); 
     paint.setColor(BORDER_COLOR); 
     canvas.drawRect(0, 0, res.getWidth(), res.getHeight(), paint); 

     canvas.drawBitmap(CAPTURE_IMAGE, BORDER_WIDTH, BORDER_WIDTH, paint); 
     Matrix mat = new Matrix(); 
     // Set the Imageview position 
     mat.postRotate(355); 

     bMapRotate = Bitmap.createBitmap(res, 0, 0, res.getWidth(), 
       res.getHeight(), mat, true); 
     System.gc(); 
     res.recycle(); 
     res = null; 
     paint = null; 
     canvas = null; 
     mat = null; 
     // Set the captured bitmap image in the imageview 
     mShareImageView.setImageBitmap(bMapRotate); 
+1

我已經創建了一個很好的JNI解決方案,通過刪除最大堆大小限制屏障來避免內存不足。 [**這裏有一個鏈接**](http://stackoverflow.com/questions/14398670/android-rotating-a-bitmap-using-jni-ndk#comment20033361_14398670)到我的片段。一些注意事項: - 在代碼中將「uint16_t」的每個實例替換爲「uint32_t」(這是我詢問的代碼上的錯誤)。 - 輸入和輸出位圖必須使用8888 config(即ARGB) - 輸入位圖將在此過程中回收。 - 代碼以時鐘方式旋轉圖像90度計數器。當然你可以根據 – 2013-01-18 13:18:20

回答

3

我認爲你應該使用收縮功能這樣

bMapRotate = Bitmap.createBitmap(res, 0, 0, res.getWidth(), 
       res.getHeight(), mat, true); 


Bitmap myBitmap = ShrinkBitmap(bMapRotate , 300, 300); 

mShareImageView.setImageBitmap(myBitmap); 


private Bitmap ShrinkBitmap(String file, int width, int height) { 
     // TODO Auto-generated method stub 
     BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); 
     bmpFactoryOptions.inJustDecodeBounds = true; 
     Bitmap bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions); 

     int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height); 
     int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width); 

     if (heightRatio > 1 || widthRatio > 1) 
     { 
     if (heightRatio > widthRatio) 
     { 
      bmpFactoryOptions.inSampleSize = heightRatio; 
     } else { 
      bmpFactoryOptions.inSampleSize = widthRatio; 
     } 
     } 

     bmpFactoryOptions.inJustDecodeBounds = false; 
     bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions); 
    return bitmap; 
    } 

它爲我工作,我避免了位圖VM內存異常

+1

來更改它。Hi.Thanks for reply.But在ShrinkBitmap方法中它傳遞了一個我沒有的參數File。 – Arun 2012-07-23 07:34:13

+1

但是您必須從某些地方選取文件,而不能使用該文件 – 2012-07-23 07:37:52

+1

這會更改生成的圖像大小... – Caner 2012-07-23 07:43:26

1

嘗試移動gc()調用結束。

res.recycle(); 
    res = null; 
    paint = null; 
    canvas = null; 
    mat = null; 
    System.gc(); 
3

在mainfest文件中添加--->的android:設置res = null後,以便它可以釋放未使用的內存應該運行largeHeap: 「真正的」

+0

只爲他人提供一個說明:我試圖將這個放在清單中的''標記中,導致錯誤的那個標記,它不起作用。但是當我把它放在''標籤中時,它就起作用了。另外,應該是'android:largeHeap =「true」'。只使用一個冒號。 – Azurespot 2015-04-06 06:18:57

0

只需添加機器人:largeHeap =「真「在您的清單文件中

Ref:largeHeap = true manifest tag not working?