BitmapFactory這個類提供了多個解析方法(decodeByteArray, decodeFile, decodeResource等)用於創建Bitmap對象,我們應該根據圖片的來源選擇合適的方法。比如SD卡中的圖片可以使用decodeFile方法,網絡上的圖片可以使用decodeStream方法,資源文件中的圖片可以使用decodeResource方法。這些方法會嘗試爲已經構建的bitmap分配內存,這時就會很容易導致OOM出現。爲此每一種解析方法都提供了一個可選的BitmapFactory.Options參數,將這個參數的inJustDecodeBounds屬性設置爲true就可以讓解析方法禁止爲bitmap分配內存,返回值也不再是一個Bitmap對象,而是null。雖然Bitmap是null了,但是BitmapFactory.Options的outWidth、outHeight和outMimeType屬性都會被賦值。這個技巧讓我們可以在加載圖片之前就獲取到圖片的長寬值和MIME類型,從而根據情況對圖片進行壓縮。如下代碼所示:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
研究
public class TestActivity extends AppCompatActivity {
@Override
public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
setContentView(R.layout.fragment_base);
ImageView iv0 = (ImageView) findViewById(R.id.iv0);
Bitmap bitmap = decodeSampleBitmapForResource(getResources(), R.drawable.timg, 124, 124);
Log.e("lzz","change size---" + bitmap.getByteCount());//65536
iv0.setImageBitmap(bitmap);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.timg, options);
Log.e("lzz","normal size---" + bitmap2.getByteCount()); //4194304
}
private Bitmap decodeSampleBitmapForResource(Resources res, int resId, int reqWidth, int reqHeight) {
// 第一次解析將inJustDecodeBounds設置爲true,來獲取圖片大小
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// 調用上面定義的方法計算inSampleSize值
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// 使用獲取到的inSampleSize值再次解析圖片
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// 源圖片的高度和寬度
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if(height > reqHeight || reqWidth > width){
// 計算出實際寬高和目標寬高的比率
final int heightRatio = Math.round((float) height / (float)reqHeight);
final int widthRatio = Math.round((float) width / (float)reqWidth);
//計算縮放比例
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
Log.e("lzz","reqWidth--" + reqWidth + "//reqHeight" + reqHeight);
Log.e("lzz","width--" + width + "//height" + height);
Log.e("lzz","inSampleSize--" + inSampleSize);
return inSampleSize;
}
//reqWidth--124//reqHeight124
//width--1024//height1024
//inSampleSize--8
//change size---65536
//normal size---4194304
}