Bitmap 的高效加載

配圖



由于bitmap的特殊性以及Android對(duì)應(yīng)用所施加的內(nèi)存限制,導(dǎo)致加載bitmap的時(shí)候很容易出現(xiàn)內(nèi)存溢出。下面這個(gè)異常信息在開發(fā)中應(yīng)該時(shí)常遇到:

java.lang.OutofMemoryError : bitmap size exceeds VM budget

因此高效地加載bitmap是一個(gè)很重要也很容易被開發(fā)者忽視的問題。

1.如何高效加載bitmap

BitmapFactory類提供了四類方法:decodeFile,decodeResource,decodeStream 和 decodeByteArray ,分別用于支持文件系統(tǒng),資源,輸入流,及字節(jié)數(shù)組中加載出一個(gè)Bitmap對(duì)象,其中decodeFile 和 decodeResource 又間接調(diào)用了decodeStream方法,這四類方法最終是在android底層實(shí)現(xiàn)的,對(duì)應(yīng)著BitmapFactory類的幾個(gè)native方法。

如何高效的加載Bitmap ? ?那就是采用BitmapFactory.options來加載所需尺寸的圖片。通過BitmapFactory.Options就可以按一定的采樣率加載縮小后的圖片,將縮小后的圖片在ImageView中顯示,這樣就會(huì)降低內(nèi)存的占用從而在一定程度上避免OOM。

2.什么是采樣率

通過BitmapFactory.Options來縮放圖片,主要是用到了它的inSampleSize參數(shù),即采樣率。當(dāng)inSampleSize為1時(shí),采樣后的圖片大小為原始大小,當(dāng)inSampleSize大于1時(shí),比如2,那么采樣后的圖片其寬高均為原圖大小的1/2,像素?cái)?shù)為原圖的1/4,占有內(nèi)存的大小也為原圖的1/4。有一種特殊情況,當(dāng)inSampleSize小于1時(shí),其作用相當(dāng)于1,即無縮放效果。另外官方文檔指出,inSampleSize的值應(yīng)該總是為2的指數(shù),比如:1,2,4,8,16 等等。如果未見傳遞的inSampleSize 不為2的指數(shù),那么系統(tǒng)會(huì)向下取整并選擇一個(gè)最接近的2的指數(shù)來代替。

3.采樣流程

(1)將BitmapFactory.Options的inJustDecodeBounds參數(shù)設(shè)為true并加載圖片。

(2)從BitmapFactory.Options中取出圖片的原始寬高信息。他們對(duì)應(yīng)于outWidth 和 outHeight 參數(shù)。

(3)根據(jù)采樣率的規(guī)則并結(jié)合目標(biāo)View的所需大小計(jì)算出采樣率inSampleSize.

(4)將BitmapFactory.Options的inJustDecodeBounds 參數(shù)設(shè)為false,然后重新加載圖片。

4.采樣流程實(shí)現(xiàn)程序

public static Bitmap decodeSampledBitmapFromResource(Resources res ,int resId, int ? ? ? ? ? ? ? ?reqWidth, int reqHeight){

? ? final BitmapFactory.Options options = new BitmapFactory.Options();

? ? options.inJustDecodeBounds = true;

? ? BitmapFactory.decodeResource(res, resId, options);

? ? options.inJustDecodeBounds? = false;

? ? return BitmapFactory.decodeResource(res, resId, options);

}

public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight){

? ? final int width = options.outWidth;

? ? final int height = options.outHeight;

? ? int inSampleSize = 1;

? ? if(height > reqHeight || width > reqWidth){

? ? ? ? ?final int halfHeight = height/2;

? ? ? ? ?final int halfWidth = width/2;

? ? ? ? while((halfHeight /inSampleSize) >reqHeight

? ? ? ? ? ? ? ?&& (halfWidth /inSampleSize) >halfWidth){

? ? ? ? ? ? ? inSampleSize *=2;

? ? ? ? ? ? ? }

? ? ? }

? ? ? return inSampleSize;

}


PS: 本文是對(duì)《Android 開發(fā)藝術(shù)探索》一書的閱讀筆記,想了解原文 請(qǐng)自行搜索。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、為什么Bitmap需要高效加載? 現(xiàn)在的高清大圖,動(dòng)輒就要好幾M,而Android對(duì)單個(gè)應(yīng)用所施加的內(nèi)存限制,...
    Android進(jìn)階與總結(jié)閱讀 4,486評(píng)論 0 2
  • 關(guān)于圖片的加載,現(xiàn)在已經(jīng)有很多主流的框架,如Glide,Volley等幫我們快速實(shí)現(xiàn)。其實(shí)這其中都包含了圖片高效加...
    Ruheng閱讀 3,762評(píng)論 11 32
  • 2021期待與你一起共事,點(diǎn)擊查看崗位[http://www.itdecent.cn/p/6f4d67fa406...
    閑庭閱讀 17,030評(píng)論 0 75
  • 本章節(jié)討論的是安卓圖片加載的基礎(chǔ)部分,主要依據(jù)谷歌官方培訓(xùn)教程中的代碼和方法,使用比較廣泛的圖片加載框架,很多都是...
    spring_chicken閱讀 1,101評(píng)論 0 3
  • 最近由于工作不穩(wěn)定,資金周轉(zhuǎn)不過來,然后才突然發(fā)現(xiàn),自己好像很危險(xiǎn)!我所處的行業(yè),行情不容樂觀,一旦失去工作,基本...
    聽哥說心里話閱讀 236評(píng)論 0 0

友情鏈接更多精彩內(nèi)容