Android應用開發之(你必須知道的“避免記憶體溢出圖片處理方案”)

來源:互聯網
上載者:User

 今天給大家分享一些圖片處理常用技術方案,Android應用開發的朋友必須要瞭解呀!

眾所周知在Android應用開發中在對圖片處理時,稍有不慎就會出現以下異常:

java.lang.OutofMemoryError: bitmap size exceeds VM budget.

以下幾點是載入Bitmap時需要謹慎對待的原因:

  • 通常行動裝置的系統資源有限,Android裝置會給每個應用程式指派16M的記憶體空間。 Android的相容性定義檔案(CDD)中第3.7節。提供了虛擬機器的相容性所需的各種螢幕尺寸和密度及最低的應用程式的記憶體。最佳化應用程式應參考這個最小的記憶體限制。然而,許多廠商的Android裝置的系統會較高的限制配置。

  • Bitmap會佔用大量的記憶體,尤其是帶有豐富的映像的應用,像照片管理等應用。例如, 在Galaxy Nexus相機拍照的最高的為2592x1936像素(5百萬像素)。如果使用bitmap 配置是ARGB_8888(預設從Android2.3起),那麼這個圖片載入到記憶體需要大約19MB的記憶體(2592*1936*4個位元組),在某些裝置上會立即耗盡應用程式的記憶體導致異常發生。

  • Android應用程式UI的經常需要一次載入多個圖片。如在ListView,GridView和ViewPager中,通常在一屏中包括在多張圖片。

如何高效的載入圖片

圖片尺寸與大小各種各樣。多數情況下大於使用者要在應用中使用的圖片大小。例如:系統的Gallery應用中管理相機拍的照片時 , 照片的尺寸像素往往大於螢幕的密度。

基於記憶體限制的原因,理想情況下你需要載入低解析度的圖片到記憶體中。低解析度的圖片與UI控制項的大小保持一致即可,高解析度的圖片對使用者來說並不明顯,然而對圖片進行縮放操作也會佔用寶貴的記憶體和額外的效能開銷。

今天給大家分享一下如何不佔用記憶體空間情況下對圖片進行縮放採樣。

讀取Bitmap 的尺寸與類型

 BitmapFactory類提高多種方法(decodeByteArray(), decodeFile(), decodeResource(), 等等)用來從不同資源檔中載入圖片。根據圖片資源類型選擇相應的方法進行載入,這些方法在構造Bitmap對象時會費配記憶體,因此很容易導致OutOfMemory異常,你可以通過 BitmapFactory.Options類為不同解碼方式參數;設定inJustDecodeBounds 為true是可以避免記憶體配置,結果為Null,但是附帶了outWidth, outHeight
and outMimeType.資訊。通過這種方式你就可以在構在Bitmap對象前擷取它的尺寸/類型資訊

BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeResource(getResources(), R.id.myimage, options);int imageHeight = options.outHeight;int imageWidth = options.outWidth;String imageType = options.outMimeType;

在使用圖片前一定要檢查圖片的尺寸以避免記憶體溢出,除非你卻定使用的圖片尺寸合適且不會耗費過多的記憶體。

 

如何載入縮放的圖片到記憶體中

現在你已經知道如何擷取圖片的大小了,這樣在使用圖片時你就可以決定是載入原圖還是載入縮放的圖片了,以下幾點需要注意:

  • 估算一下原圖的記憶體使用量情況

  • 你的應用中允許分配給圖片的記憶體大小

  • 使用圖片的ImageView或其他UI組件大小。

  • 使用裝置的螢幕大小與密度

例如:1024*768的圖片實際上只需要在ImageView中顯示128*96的縮圖

在BitmapFactory.Options 中設定inSampleSize為合適的採樣率,以擷取合適尺寸的圖片。

例如:2048*1536的圖片將 inSampleSize 位置為 4時可以得到512*384的圖片,如果載入的記憶體中為0.75M,遠低於原圖的12M記憶體空間(Bitmap設定為ARGB_8888時),下面是一個基於需要的圖片大小擷取合適採樣率例子:

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,        int reqWidth, int reqHeight) {                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // First decode with inJustDecodeBounds=true to check dimensions    final BitmapFactory.Options options = new BitmapFactory.Options();    options.inJustDecodeBounds = true;    BitmapFactory.decodeResource(res, resId, options);                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // Calculate inSampleSize    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // Decode bitmap with inSampleSize set    options.inJustDecodeBounds = false;    return BitmapFactory.decodeResource(res, resId, options);}

通過上面的方法可以很容易的把一個大圖片以100*100的縮圖的大小設定到ImageView中,例子如下:

mImageView.setImageBitmap(    decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));

 

你可以參考上面的方式選擇你需要的載入方式載入圖片。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.