博客: 安卓之家
微博: 追风917
CSDN: 蒋朋的家
简书: 追风917
理论
Bitmap 的高效加载会利用 BitmapFactory.Options 来加载所需尺寸的图片,也就是可以按一定的采样率来加载所需图片(一般就是缩小后的图片)。采样率的设置就是 BitmapFactory.Options 的inSampleSize 参数。
- inSampleSize 小于1时,无缩放效果,相当于 inSampleSize = 1;
- inSampleSize 为1时,采样后图片为原始图片大小
- inSampleSize 为2时,采样后图片的宽高均为原始图片的一半,那么像素值为原始图片的1/4, 占内存大小也是原图的1/4,也就是说缩放比例是 1/(inSampleSize 的2次方),比如inSampleSize 为 4, 缩放比例就是 1/16
- 最新官方文档指出,inSampleSize 的取值应该是2的指数,比如1,2,4,8,16…如果inSampleSize不为2的指数,会向下取整选择一个最接近的2的指数来代替,比如3,系统会选择2来代替,但是验证发现该结论并非所有的安卓系统版本都成立,因此这只是一个开发建议咯。
步骤
- 把 BitmapFactory.Options 的inJustDecodeBounds 参数设置为 true,此时BitmapFactory 只会解析原始图片的宽高信息,不会真正加载图片
- 从 BitmapFactory.Options 中取出图片宽高信息,它们对应于outWidth 和 outHeight 参数
- 根据采样率的规则并结合目标View所需大小计算采样率 inSampleSize
- 把 BitmapFactory.Options 的inJustDecodeBounds 参数设置为 false, 重新加载图片
具体代码实现
计算分辨率
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// 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;
}
加载图片
public static Bitmap decodeBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final 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);
}
我写到了这个 Gist
使用
mImageView.setImageBitmap(
decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
参考内容:
任书记的《Android 开发艺术探索》第 12 章
google开发指南
分享是一种美德,更是一种生活方式!!
也许你会说我是一个梦想者,但我不是唯一的一个。
悦分享,越快乐^_^
欢迎交流,转载请注明出处,谢谢!