Bitmap 處理 之載入大的Bitmap

來源:互聯網
上載者:User
流暢的載入大的Bitmap
原文串連 http://developer.android.com/intl/zh-CN/training/displaying-bitmaps/load-bitmap.html#read-bitmap
在處理Bitmap的過中經常遇到的問題是OOM,尤其是在載入像素比較大的bitmap時,出現這種問題的機率比較高。在載入圖片的時候,就要考慮是否真的需要那麼大像素的bitmap,如果要顯示的ImageView的大小是120x140,但是要載入的資源的圖片是1024X768的,這時候如果直接載入資源很容易出現OOM的問題,如果在載入圖片之前能夠知道圖片的像素的大小,然後在適當的壓縮處理,然後在顯示出來,這樣OOM的問題就比較不容易出現。
讀取Bitmap的大小和類型
BitmapFactory提供了很多方法來解析方法(decodeByteArray(), decodeFile(), decodeResource()等等)來建立bitmap,你可以選擇一個合適的方法來建立bitmap,但是這樣直接的建立bitmap和容易引起OOM,BitmapFactory還提供一組配套的方法來建立bitmap,需要加上BitmapFactory.Options的參數,在顯示bitmap之前事先讀取bitmap的大小和類型:
BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeResource(getResources(), R.drawable.myimage, options);int imageHeight = options.outHeight;int imageWidth = options.outWidth;String imageType = options.outMimeType;

將BitmapFactory.Options的inJustDecodeBounds設定為true,可以在解析bitmap之前獲得bitmap的大小和類型
壓縮bitmap之後,再載入到記憶體
在顯示bitmap之前,需要獲得目標顯示的bitmap的大小和要載入的bitmap的大小,然後計算出來一個合適的壓縮比,把通過壓縮過的bitmap載入到記憶體中,下面是一個封裝的方法,來計算合適的壓縮比

 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) {           // Calculate ratios of height and width to requested height and           // width           final int heightRatio = Math.round((float) height / (float) reqHeight);           final int widthRatio = Math.round((float) width / (float) reqWidth);           // Choose the smallest ratio as inSampleSize value, this will           // guarantee           // a final image with both dimensions larger than or equal to the           // requested height and width.           inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;       }       return inSampleSize;   }

其中 reqWidth,reqHeight是目標的寬的和高度,height,width是資源的高度和寬的,然後計算出一個壓縮的比例,使用最小的壓縮比
要使用這個方法,首先將inJustDecodeBounds 設定為true,解析獲得資源的大小和類型,然後通過上面的方法獲得壓縮比,然後再將inJustDecodeBounds設定為false,通過計算出來的要所比來解析最終要顯示的bitmap

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

例子: imageView的顯示,ImageView要顯示的映像的大小是100X100,實際的映像可能不是100X100,通過上面的方法做一下壓縮處理,這樣就避免出現OOM的問題 mImageView.setImageBitmap(

   decodeSampledBitmapFromResource(getResources(), R.drawable.myimage, 100, 100)); 上面是通過解析decodeSampledBitmapFromResource 資源檔獲得bitmap,當然還有其他的方法來獲得bitmap

  1. 通過檔案獲得bitmap
public static Bitmap decodeSampledBitmapFromFile(String filename,           int reqWidth, int reqHeighte) {       // First decode with inJustDecodeBounds=true to check dimensions       final BitmapFactory.Options options = new BitmapFactory.Options();       options.inJustDecodeBounds = true;       BitmapFactory.decodeFile(filename, options);       // Calculate inSampleSize        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);       // Decode bitmap with inSampleSize set       options.inJustDecodeBounds = false;       return BitmapFactory.decodeFile(filename, options);   
   2.通過FileDescriptor獲得bitmap
public static Bitmap decodeSampledBitmapFromDescriptor(           FileDescriptor fileDescriptor, int reqWidth, int reqHeight, ImageCache cache) {       // First decode with inJustDecodeBounds=true to check dimensions       final BitmapFactory.Options options = new BitmapFactory.Options();       options.inJustDecodeBounds = true;       BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);       // Calculate inSampleSize       options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);       // Decode bitmap with inSampleSize set       options.inJustDecodeBounds = false;       return BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);   }

聯繫我們

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