1.加载Bitmap常规操作
简单来说,就是采用bitmapFactory.Options来加载所需尺寸的图片,然后按一定的采样率来加载缩小后的图片。
通过BitmapFactory.Options来缩放图片,主要是用到了它的inSampleSize参数,即采样率。当inSampleSize为1时,采样后的图片大小为图片的原始大小;当大于1,比如2,那么采样后的图片其宽高均为原图大小的1/2,而像素数为原图的1/4,其占有的内存大小也为原图的1/4。
需要注意的事,采样率inSampleSize必须是大于1的整数,图片才会有缩小效果,并且采样率同时作用于宽/高,这将导致缩放后的图片大小以采样率的2次方形式递减,即缩放比例为1/(inSampleSize的2次方)。还有就是小于1时,不起作用。
2.如何获取采样率?
(1) 将BitmapFactory.Options的inJustDecodeBounds参数设为true并加载图片。
(2) 从BitmapFactory.Options中取出图片的原始宽高信息,它们对应于outWidth和outHeight参数。
(3) 根据采样率的规则并结合目标view的所需大小计算出采样率inSampleSize。
(4) 将BitmapFactory.Options的inJustDecodeBounds参数设为false,然后重新加载图片。
当inJustDecodeBounds参数设为true时,BitmapFactory只会解新图片的原始宽/高信息,并不会去真正地加载图片。
把上述翻译成代码:
public staic Bitmap decodeSampledBitmapFromResource(Resource res, int resId, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
fianl BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
if (reqWidth == 0 || reqHeight == 0) {
return 1;
}
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height/2;
final int halfWidth = width/2;
// Calculate the largest inSampleSize value that is a power of 2 and
// keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}