其實(shí)Bitmap的二次采樣就那么回事,別怕,我們現(xiàn)在來雞婆它!
1、為什么要二次采樣
Android app開發(fā)過程中,加載大圖或者多圖都有可能造成內(nèi)存溢出問題(OOM)。
2、二次采樣分別是哪兩次,目的是什么?
第一次采樣:主要為了獲取圖片的壓縮比例,假如一張400400的圖片,要將他顯示在5050的ImageView中,則壓縮比為8,那么8怎么來的?
首先將圖片的邊界加載到內(nèi)存中(inJustDecodeBounds = true, decodeFile())。然后獲取到圖片的寬高參數(shù),然后結(jié)合控件的寬高計(jì)算出縮放比例。
第二次采樣:二次采樣的時(shí)候,我把第一次采樣后算出來的結(jié)果作為一個(gè)參數(shù)傳遞給第BitmapFactory,這樣在加載圖片的時(shí)候系統(tǒng)就不會(huì)將整張圖片加載進(jìn)來了,而是只會(huì)加載該圖片的一張縮略圖進(jìn)來,這樣不僅提高了加載速率,而且也極大的節(jié)省了內(nèi)存,而且對(duì)于用戶來說,他也不會(huì)有視覺上的差異。
3、代碼如下
public class BitmapUtils {
/**
*
* @param filePath 文件路徑
* @param desWidth 顯示圖片的控件的寬度
* @param desHeight 顯示圖片的控件的高度
* @return
*/
public static Bitmap getBitmap(String filePath, int desWidth, int desHeight) {
//第一次采樣
BitmapFactory.Options options = new BitmapFactory.Options();
//該屬性設(shè)置為true只會(huì)加載圖片的邊框,并不會(huì)加載圖片的具體像素點(diǎn)
options.inJustDecodeBounds = true;
//第一次加載圖片,這時(shí)只會(huì)加載圖片的邊框進(jìn)來. decode有很多方法,可以隨便選
BitmapFactory.decodeFile(filePath, options);
//獲取原圖的寬和高
int outWidth = options.outWidth;
int outHeight = options.outHeight;
//定義縮放比例
int sampleSize = 1;
//如果寬高的任意一方的縮放比例沒有達(dá)到要求,都繼續(xù)增大縮放比例
while(outHeight/sampleSize > desHeight || outWidth/sampleSize >desWidth){
//sampleSize應(yīng)該為2的n次冪,如果給sampleSize設(shè)置的數(shù)字不是2的n次冪,那么系統(tǒng)會(huì)就近取值
sampleSize *= 2;
}
/********************************************************************************************/
//至此,第一次采樣已經(jīng)結(jié)束,我們已經(jīng)成功的計(jì)算出了sampleSize的大小
/********************************************************************************************/
//第二次采樣
//設(shè)置為加載圖片
options.inJustDecodeBounds = false;
//設(shè)置縮放比例
options.inSampleSize = sampleSize;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
return bitmap;
}
}