安卓 Bitmap 高效加载

博客: 安卓之家
微博: 追风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来代替,但是验证发现该结论并非所有的安卓系统版本都成立,因此这只是一个开发建议咯。

步骤


  1. 把 BitmapFactory.Options 的inJustDecodeBounds 参数设置为 true,此时BitmapFactory 只会解析原始图片的宽高信息,不会真正加载图片
  2. 从 BitmapFactory.Options 中取出图片宽高信息,它们对应于outWidth 和 outHeight 参数
  3. 根据采样率的规则并结合目标View所需大小计算采样率 inSampleSize
  4. 把 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开发指南

分享是一种美德,更是一种生活方式!!

也许你会说我是一个梦想者,但我不是唯一的一个。

悦分享,越快乐^_^

欢迎交流,转载请注明出处,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值