Bitmap在Android中指的是一張圖片垦细,可以是png格式也可以是jpg等其他常用的圖片格式.
如何加載bitmap?
BitmapFactory類提供了四個(gè)static方法: decodeFile, decodeResource, decodeStream和decodeByteArray.
Bitmap icon = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.frequent_default);
高效加載bitmap的核心思想
就是通過BitmapFactory.Options類的對(duì)象砂代, 設(shè)置合理的inSampleSize屬性值本昏, 然后把option對(duì)象傳給剛提到的加載bitmap的四個(gè)static方法, 它們都支持BitmapFactory.Options這個(gè)參數(shù).
public static Bitmap decodeResource(Resources res, int id, Options opts)
inSampleSize: 采樣率
一張10241024像素的圖片值朋,假定采用ARGB8888格式存儲(chǔ),占內(nèi)存大小為102410244, 即4MB. 如果inSampleSize為2秤标,那么采樣后的圖片寬高為原來的1/2揪阶,即512512像素, 占內(nèi)存大小為5125124睬罗, 即1MB.
注意兩點(diǎn):
- 設(shè)置inSampleSize值小于1時(shí)轨功,其作用相當(dāng)于1, 即無縮放效果.
- 官方文檔建議inSampleSize值為2的指數(shù), 即1傅物,2夯辖,4,8董饰,16,等等.
設(shè)置合理的inSampleSize值
考慮以下的實(shí)際情況蒿褂, 假設(shè)ImageView的大小為100100像素圆米,而圖片的原始尺寸為200200,那么設(shè)置inSampleSize為2即可啄栓,如果圖片原始尺寸為200300娄帖,設(shè)置inSampleSize為2,縮小后的圖片尺寸是100150昙楚,設(shè)給這個(gè)ImageView也沒問題近速, 但如果設(shè)置inSampleSize為4, 縮小后的尺寸為50*75堪旧,達(dá)不到ImageView所期望的大小削葱, 這時(shí)候這個(gè)圖片就會(huì)被拉伸從而導(dǎo)致模糊, 這顯然不是我們所期望看到的.
獲取合理的采樣率也簡(jiǎn)單, 可通過如下的流程:
- 將BitmapFactory.Options的inJustDecodeBounds參數(shù)設(shè)為true并加載圖片.
- 從BitmapFactory.Options中取出圖片的原始寬高淳梦,它們對(duì)應(yīng)于outWidth和outHeight參數(shù).
- 結(jié)合目標(biāo)View所需大小析砸,計(jì)算出inSampleSize的值.
- 將BitmapFactory.Options的inJustDecodeBounds參數(shù)設(shè)為false,然后從新加載圖片.
這里說明一下inJustDecodeBounds參數(shù)的含義爆袍,當(dāng)此參數(shù)為true時(shí)首繁,BitmapFactory只會(huì)解析圖片的原始寬高信息, 并不會(huì)去真正的加載圖片陨囊,所以這個(gè)操作是輕量級(jí)的.
對(duì)上面的流程用代碼實(shí)現(xiàn)下:
public static Bitmap decodeResourceEx(Resources res, int resId, int reqWidth, reqHeight) {
//first, decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, id, options);
int originWidth = options.outWidth;
int originHeight = options.outHeight;
//calculate inSampleSize
options.inSampleSize = calculateInSampleSize(originWidth, originHeight, reqWidth, reqHeight);
//Decode bitmap with inSampleSize
options.inJustDecodeBounds = false;
return BitmapFacotry.decodeResource(res, resId, options);
}
private int calculateInSampleSize(originWidth, originHeight, reqWidth, reqHeight) {
int inSampleSize = 1;
if(originWidth>reqWidth || originHeight>reqHeight) {
final int halfWidth = originWidth / 2;
final int halfHeight = originHeight / 2;
//calculate the largest inSampleSize value that is a power of 2 and keeps both height and width larger than the requested height and width.
while(((halfWidth/inSampleSize) >= reqWidth) &&((halfHeight/inSampleSize) >= reqHeight)) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
比如ImageView所期望的圖片大小是100*100像素弦疮,這個(gè)時(shí)候就可以通過如下方式高效地加載并顯示圖片:
mImageView.setImageBitmap(decodeResourceEx(getResources(), R.id.myImage, 100, 100));