版權(quán)聲明:本文源自簡書tianma,轉(zhuǎn)載請務(wù)必注明出處: http://www.lxweimin.com/p/2f1ce7d0d64c
OOM即Out Of Memory的簡稱,Android平臺避免OOM異常的發(fā)生是非常有必要的。而在Android中加載大量大圖便可能會導(dǎo)致OOM異常的出現(xiàn),解決的辦法之一就是加載圖片之前對圖片進(jìn)行壓縮然后再獲取圖片對應(yīng)的Bitmap對象,那么應(yīng)該如何操作呢?如下:
/**
* 通過圖片的絕對路徑來獲取對應(yīng)的壓縮后的Bitmap對象
*/
public static Bitmap getCompressedBitmap(String filePath, int requireWidth,
int requireHeight) {
// 第一次解析將inJustDecodeBounds設(shè)置為true,用以獲取圖片大小,并且不需要將Bitmap對象加載到內(nèi)存中
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options); // 第一次解析
// 計(jì)算inSampleSize的值,并且賦值給Options.inSampleSize
options.inSampleSize = calculateInSampleSize(options, requireWidth,
requireHeight);
// 使用獲取到的inSampleSize再次解析圖片
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filePath, options);
}
/**
* 通過圖片資源id獲取圖片對應(yīng)的壓縮后的Bitmap對象
*/
public static Bitmap getCompressedBitmap(Resources res, int resId, int requiredWidth, int requiredHeight) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);// 第一次解析
options.inSampleSize = calculateInSampleSize(options, requiredWidth,
requiredHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);// 第一次解析
}
/**
* 計(jì)算壓縮的inSampleSize的值,該值會在寬高上都進(jìn)行壓縮(也就是壓縮前后比例是inSampleSize的平方倍)
*/
private static int calculateInSampleSize(BitmapFactory.Options options,
int requireWidth, int requireHeight) {
// 獲取源圖片的實(shí)際的寬度和高度
int realWidth = options.outWidth;
int realHeight = options.outHeight;
int inSampleSize = 1;
if (realWidth > requireWidth || realHeight > requireHeight) {
// 計(jì)算出實(shí)際的寬高與目標(biāo)寬高的比例
int widthRatio = Math.round((float) realWidth
/ (float) requireWidth);
int heightRatio = Math.round((float) realHeight
/ (float) requireHeight);
// 選擇寬高比例最小的值賦值給inSampleSize,這樣可以保證最終圖片的寬高一定會大于或等于目標(biāo)的寬高
inSampleSize = widthRatio < heightRatio ? widthRatio : heightRatio;
}
return inSampleSize;
}
以上代碼中,有一點(diǎn)值得商榷:
到底是要讓圖片顯示完全還是讓圖片寬高和需要的寬高一致呢?
如果需要讓圖片寬高和需要的寬高一致的話,就選擇比率小的:
inSampleSize = widthRatio < heightRatio ? widthRatio : heightRatio;
如果需要讓圖片顯示完全的話,就選擇比率大的:
inSampleSize = widthRatio > heightRatio ? widthRatio : heightRatio;
如果兩者都要兼顧的話,就讓方法多設(shè)置參數(shù),讓調(diào)用者決定去吧! :)
參考鏈接:
Displaying Bitmaps Efficiently
Android高效加載大圖、多圖解決方案,有效避免程序OOM