在图片加载时,如果不对图片进行处理,会报OOM异常,为了解决这一问题,需要在图片加载时对图片进行压缩,采用二次采样可以有效避免OOM问题。
二次采样主要是通过缩小图片,减少图片的像素指数来实现,我们通过BitMapFactory.Options来缩放图片,主要使用BitmapFactory.Options.inSampleSize参数,inSampleSizeca参数被称为采样率,当采样率为1时,图片的高和宽等于图片的原始高和宽,当采样率为2时,图片的高和宽都为原图的1/2,像素数为原图的1/4,图片的像素数会随着采样率的增加以二次方的形式递减,采样率规定取值为2的指数,如果取得采样率不是2的指数就会向下去最近的2的指数值。BitmapFactory.Options提供了另一个参数inJustDecodeBounds,设置inJustDecodeBounds为true后,decodeFile并不分配空间,但可计算出原始图片的长度和宽度,即opts.width和opts.height。有了这两个参数,再通过一定的算法,即可得到一个恰当的inSampleSize。
//获得采样率
public int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth,int reqHeight){
if (reqWidth==0||reqHeight==0){
return 1;
}
//获取图片的宽和高
int outHeight = options.outHeight;
int outWidth = options.outWidth;
MyLog.d(TAG, "origin w = "+ outWidth+"h = "+outHeight);
int inSampleSize = 1;
if (reqHeight>outHeight||reqWidth>outWidth){
int halfHeiht = reqHeight/2;
int halfWidth = reqWidth/2;
while ((halfHeiht/inSampleSize)>reqHeight&&(halfWidth/inSampleSize)>reqWidth){
inSampleSize*=2;
}
MyLog.d(TAG, "inSampleSize="+inSampleSize);
}
return inSampleSize;
}
//文件中加载
public Bitmap decodeSampledbitmapFromFileDescriptor(FileDescriptor fd,
int resId,int reqWidth,int reqHeight){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds=true;
BitmapFactory.decodeFileDescriptor(fd, null, options);
options.inSampleSize=calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds=false;
return BitmapFactory.decodeFileDescriptor(fd, null, options);
}
//资源中加载
public Bitmap decodeSampledbitmapFromResource(Resources res,
int resId,int reqWidth,int reqHeight){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds=true;
BitmapFactory.decodeResource(res, resId, options);
options.inSampleSize=calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds=false;
return BitmapFactory.decodeResource(res, resId, options);
}