Android如何高效顯示較大的Bitmaps_Android

來源:互聯網
上載者:User

一、高效載入較大的Bitmaps

     圖片有各種形狀和各種大小,在很多情況下,圖片的實際大小都比圖片在應用中所顯示的大小要大的多,比如Android系統內建的 Gallery  應用顯示的照片實際的解析度通常比手機裝置的密度要高很多

     考慮到我們是在開發一款記憶體使用量受限的應用,理想的情況下,我們只是想把一個低解析度版本的位元影像載入記憶體,一般來說這個低解析度版本的位元影像要跟UI元件實際需要顯示的大小相符。一張高解析度的圖片並不會給我們帶來任何明顯的好處,但卻會佔用寶貴的記憶體資源和產生額外的效能開銷

二、擷取Bitmap的尺寸大小和類型

     BitmapFactory 類為我們提供了幾種decoding方法(decodeByteArray(), decodeFile(),decodeResource(), etc)來從不同的來源建立出 Bitmap ,如何選擇最恰當的decode方法取決於你的圖片資料來源,這些方法都會去嘗試申請記憶體來構建Bitmap對象,所有很容易就會導致一個OutOfMemory  異常,每種類型的decode方法都有額外的簽名來讓你通過 BitmapFactory.Options 類來指定decoding選項,當我們decoding的時候把inJustDecodeBounds 屬性設定為true 可以避免申請記憶體,雖然會返回一個null Bitmap對象 ,但是會為我們傳入的BitmapFactory.Options  對象設定 outWidth, outHeight and outMimeType 等屬性的值,這個技術可以讓你在構建Bitmap對象之前事Crowdsourced Security Testing道它的大小和類型

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; 

為了避免java.lang.OutOfMemory  異常,在decoding Bitmap之前你有必要去檢測Bitmap的大小和類型,除非你真的是非常清楚你要decoding的Bitmap的大小,還有這個大小要適合當前應用記憶體環境

三、載入‘縮小版'的Bitmap到記憶體

     現在我們已經知道了Bitmap的大小,這將有助於我們來決策是載入整張Bitmap還是載入'縮小版'的Bitmap,這裡有一些因素需要進行考慮:

1、載入整張圖片預計要使用多少記憶體

2、在考慮到其它方面記憶體需要的情況下,你想把多少數量的記憶體給Bitmap使用:

3、用於顯示Bitmap的 ImageView 控制項或其它UI元件的大小

4、當前裝置螢幕的大小和密度    

例如,一點都不值得載入1024x768  像素的圖片到記憶體中,而最終只在128x96 像素大小的 ImageView 控制項上顯示       

我們應該告訴decoder,映像需要進行抽樣,載入一個更小號的Bitmap到記憶體中,設定 BitmapFactory.Options 對象的 inSampleSize 屬性為true 。例如,一張解析度為2048x1536 像素的圖片,如果decode的時候把inSampleSize   設定為4,那麼得到的最終圖片的大小大約為512x384 ,載入記憶體耗費0.75M而不是載入整張時的12M (假設位元影像的配置為 ARGB_8888) ,下面有一個在目標高和寬基礎上計算inSampleSize 的方法

public static int calculateInSampleSize(    BitmapFactory.Options options, int reqWidth, int reqHeight) {  // Raw height and width of image  final int height = options.outHeight;  final int width = options.outWidth;  int inSampleSize = 1;   if (height > reqHeight || width > reqWidth) {   if (width > height) {    inSampleSize = Math.round((float)height / (float)reqHeight);   } else {    inSampleSize = Math.round((float)width / (float)reqWidth);   }  }  return inSampleSize; } 

NOTE :  inSampleSize  值是2的冪的話,對於decoder來說會更快和更高效。然而,如果你想把調整過大小的位元影像緩衝到記憶體或硬碟上時,依然非常有意義decoding最合適的位元影像大小,這樣有助於節省記憶體或節省硬碟空間

下面是一個擷取位元影像的方法

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); } 

這個方法可以很容易的做到在任意顯示尺寸大小的UI元件中去載入一張位元影像

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

在其他的BitmapFactory.decode*  系列的decode方法中以上擷取位元影像的技術也是需要的。

以上就是本文的全部內容,希望對大家學習Android軟體編程有所協助。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.