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
}