原文鏈接:http://blog.csdn.net/u012810020/article/details/51729264
理論部分
一、 如何加載一個(gè)Bitmap
Bitmap在Android中指的是一張圖片饵溅,可以使PNG格式也可以是JPG等常見的其他圖片的格式。Android提供了四類方法加載Bitmap:decodeFile、decodeResource髓削、decodeStream和decodeByteArray驯用。分別用于從文件系統(tǒng)驼鞭、資源、輸入流以及字節(jié)數(shù)組中加載一個(gè)Bitmap對(duì)象衫贬,其中decideFile和decodeResource又間接調(diào)用了decodeStream方法德澈。
高效加載Bitmap思想:采用BitmapFactory.Options來(lái)加載所需尺寸的圖片。通過(guò)Bitmap.Options來(lái)縮放圖片固惯,主要使
用它的inSampleSize參數(shù)梆造,即采樣率。當(dāng)inSampleSize為1時(shí)葬毫,采用后的圖片大小為原始圖片大姓蚧浴;當(dāng)inSampleSize的至大
于1時(shí)贴捡,比如為2忽肛,那么采樣后的圖片的寬和高均為原來(lái)的1/2,而像素為原始的1/4,其占有的內(nèi)存大小也為原來(lái)的1/4烂斋。拿一張1024*1024像素
的圖片來(lái)說(shuō)屹逛,假定采用ARGB8888格式存儲(chǔ)础废,那么它占有的內(nèi)存為1024x1024x4,即4M煎源,如果inSampleSize為2色迂,那么采樣后的圖
片占有內(nèi)存為512x512x4,即1M手销。
二歇僧、實(shí)際問題
我們來(lái)考慮一下實(shí)際問題:比如ImageView的大小是100x100像素,而原始圖片的大小為200x200像素锋拖,那么只需要將采樣率
inSampleSize設(shè)置為2就OK了诈悍,但是如果圖片大小為200x300呢?這個(gè)時(shí)候的采樣率仍設(shè)置為2兽埃,這樣縮放后的圖片大小為100x150像
素侥钳,仍然是適合ImageView的,如果采樣率為3柄错,那么縮放后的圖片的大小就會(huì)小于ImageView所期望的大小舷夺,這樣圖片就會(huì)被拉伸從而導(dǎo)致模
糊。
通過(guò)采樣率加載圖片售貌,主要的就是計(jì)算出合適的采樣率给猾,計(jì)算采樣率的一般流程:
①將BitmapFactory.Options的inJustDecodeBounds參數(shù)設(shè)置為true并加載圖片。
②從BitmapFactory.Options中取出原始圖片的寬高信息颂跨。
③根據(jù)采樣率的規(guī)則并結(jié)合目標(biāo)View所需大小計(jì)算出采樣率inSampleSize敢伸。
④將BitmapFactory.OPtions的參數(shù)設(shè)置為false并重新加載圖片。
通過(guò)上面4個(gè)步驟恒削,加載出的圖片就是最終縮放的圖片池颈,當(dāng)然也有可能不需要縮放。這里解釋一下inJustDecodeBounds參數(shù)钓丰,當(dāng)參數(shù)為true
時(shí)躯砰,BitmapFactory只會(huì)解析圖片的原始寬高信息,并不會(huì)真正的去加載圖片携丁。所以這個(gè)操作是輕量級(jí)的弃揽。另外需要注意的是,這個(gè)時(shí)候
BitmapFactory獲取的圖片寬高信息和圖片的位置以及程序運(yùn)行的設(shè)備有關(guān)则北,比如同一張圖片放在不同的drawable文件夾目錄下或者程序運(yùn)行
在不同的屏幕密度的設(shè)備上矿微,這樣導(dǎo)致BitmapFactory獲取到不同的結(jié)果。
代碼實(shí)現(xiàn)
[html]view plaincopy
/**
*?類描述:Bitmap壓縮工具類
*?Created?by?lizhenya.
*/
public?class?BitmapHelper?{
/**
*?方法描述:壓縮Resources類型的Bitmap
*
*?@param?resources?Class?for?accessing?an?application's?resources.
*?@param?resId?????圖片資源的ID
*?@param?reqWidth??Bitmap目標(biāo)壓縮寬度像素值
*?@param?reqHeight?Bitmap目標(biāo)壓縮高度像素值
*?@return?壓縮后的Bitmap類型的圖片
*/
public?static?Bitmap?decodeSampleBitmapFromResouce(Resources?resources,?int?resId,?int?reqWidth,?int?reqHeight)?{
//First?decode?withinJustDecodeBounds=trueto?check?dimension
BitmapFactory.Optionsoptions=newBitmapFactory.Options();
options.inJustDecodeBounds=true;
BitmapFactory.decodeResource(resources,?resId,?options);
//Caculate?inSampleSize
options.inSampleSize=caculateInSampleSize(options,?reqWidth,?reqHeight);
options.inJustDecodeBounds=false;
return?BitmapFactory.decodeResource(resources,?resId,?options);
}
/**
*?方法描述:計(jì)算采樣率inSampleSize的值
*
*?@param?options???BitmapFactory.Options實(shí)例
*?@param?reqWidth??Bitmap目標(biāo)壓縮寬度像素值
*?@param?reqHeight?Bitmap目標(biāo)壓縮高度像素值
*?@return?采樣率inSampleSize的值
*/
private?static?int?caculateInSampleSize(BitmapFactory.Options?options,?int?reqWidth,?int?reqHeight)?{
//Raw?height?and?width?of?image
intheight=options.outHeight;
intwidth=options.outWidth;
Log.e("TAG","Rawheight="+height);
Log.e("TAG","Rawwidth="+width);
intinSampleSize=1;
if?(height>reqHeight?||?width>reqWidth)?{
inthalfWidth=width/?2;
inthalfHeight=height/?2;
while?(halfHeight?/?inSampleSize>=?reqHeight?&&?halfWidth?/?inSampleSize>=?reqWidth)?{
inSampleSize?*=?2;
}
}
return?inSampleSize;
}
}
這篇博客主要討論的是Bitmap的加載尚揣,關(guān)于Bitmap的優(yōu)化還有一個(gè)重要的技術(shù)點(diǎn):Bitmap的緩存涌矢。