Android學習筆記:如何高效顯示圖片,避免記憶體溢出 和 ImageView無法顯示大尺寸的圖片

來源:互聯網
上載者:User

標籤:android   blog   io   使用   sp   java   for   on   div   

因為手機的記憶體資源是有限的,每個app可使用的記憶體是受限的。而現在採用高解析度拍的照片往往很大。如果載入時不注意方法,很有可能會引起java.lang.OutofMemoryError: bitmap size exceeds VM budget. 異常而導致app奔潰退出。

另外ImageView支援的圖片大小也是受限制的,比如整個App雖然只放一張圖片,該圖片大小也沒超過整個app的記憶體上限。但該圖片大小超過了ImageView的最大值,這也是有問題的。這時需要採取方法,在載入圖片時縮小載入圖片的大小。具體的策略看下面的介紹。

在真正建立和載入(需要實際耗費記憶體)一個圖片對象時,我們可以先擷取映像的大小資訊。這裡我們可以用到BitmapFactory.Options這個類。BitmapFactory.Options這個類,有一個欄位叫做 inJustDecodeBounds 。SDK中對這個成員的說明是這樣的:
“If set to true, the decoder will return null (no bitmap), but the out... fields will still be set, allowing the caller to query the bitmap without having to allocate the memory for its pixels.”

也就是說,如果我們把它設為true,那麼BitmapFactory.decodeFile(String path, Options opt)並不會真的返回一個Bitmap給你,但它會把它的寬,高等基本資料取回來給你,這樣就不會實際分配圖片所需的記憶體。代碼例子如下:

BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeResource(getResources(), R.drawable.pic1, options);String text = "imageHeight:" + options.outHeight + ",imageWidth:"+ options.outWidth + ",imageType:" + options.outMimeType;Toast.makeText(this, text, Toast.LENGTH_LONG).show();

知道了圖片的大小後,就可以考慮是將整個完整的圖片載入到記憶體中,或是將縮小版載入到記憶體中。因為手機螢幕本身大小就那麼大,沒必要將原尺寸的圖片載入進去。比如如果螢幕的大小為128x96,則將大小為1024x76的圖片載入進去就沒有意義。

為了告訴解碼器將圖片壓縮後載入到記憶體中,需要設定BitmapFactory.Options對象的 inSampleSize 屬性。比如,一張2048*1536的圖片,如果設定inSampleSize的值為4. 縮小後圖片的尺寸變為 512x384。佔用的記憶體由原來的12M變為0.75M。下面的方法可以計算出一個圖片應該設定的inSampleSize值:

public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight) {// reqWidth、reqHeight是想要顯示圖片的大小,如螢幕的大小或ImageView控制項的大小final int height = options.outHeight;final int width = options.outWidth;int inSampleSize = 1;if (height > reqHeight || width > reqWidth) {//說明圖片的真實大小,大於需要顯示的大小,則需要縮小圖片final int halfHeight = height / 2;final int halfWidth = width / 2;while ((halfHeight / inSampleSize) > reqHeight&& (halfWidth / inSampleSize) > reqWidth) {inSampleSize *= 2;}}return inSampleSize;}

  有了適當的inSampleSize值後,就可以真正的執行載入圖片的操作了。代碼如下:

 final BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; options.inJustDecodeBounds = false; Bitmap bitmap =  BitmapFactory.decodeResource(res, resId, options); ImageView imageView = (ImageView)findViewById(R.id.imageView1); imageView.setImageBitmap(bitmap);

實際上對於大的圖片,通過使用inSampleSize將圖片變小後載入到記憶體中,只要不是變了非常小,不會影響視覺效果。但來的好處是顯而意見的,會大大降低對記憶體的使用。一般對於大尺寸的照片(如用手機自身拍的),將inSampleSize設定為4一般不會影響視覺效果。

  

 

Android學習筆記:如何高效顯示圖片,避免記憶體溢出 和 ImageView無法顯示大尺寸的圖片

聯繫我們

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