Bitmap的加载和Cache

前段时间买了一本android进阶的书,可是一直忙于工作,近期闲暇就看看,今天看了Bitmap的加载和Cache这部分,因为觉得有一部分还是比较费劲,虽然读过去了还是一知半解,所以准备先记录一下相对好理解的开始部分,然后慢慢品味,慢慢记录。所以这一篇先记录一下Bitmap的加载这部分。

BitmapFactory类提供了四类方法:

decodeFile  从文件系统加载一个Bitmap对象

decodeResource  从资源加载一个Bitmap对象

decodeStream  从输入流加载一个Bitmap对象

decodeByteArray  从字节数组加载一个Bitmap对象


 加载大图的策略:

通过BitmapFactory.Options就可以按一定的采样率来加载缩小后的图片,将缩小后的图片显示在控件上,这样就能降低内存从而在一定程度上避免OOM,提高Bitmap加载时的性能。

BitmapFactory.Options缩放图片主要是用到了inSampleSize参数(采样率),当采样率的值为1的时候,相当于没有放缩,即和原图一样大,所以要实现缩小图片采样率的值就必须大于一,而且最新的官方文档指出,采样率的取值应该总是2的指数,即2,4,6,8,...。比如采样率取值2,那么最后得到的缩小图像素数和内容占用都为原图的1/4,即是宽和高都缩小了两倍。

通过采样率加载图片的流程大概可以有以下四个步骤:

1.将BitmapFactory.Options的inJustDecodeBounds参数值设置为true,并加载图片

2.从BitmapFactory.Options中取出图片的原始宽和高的信息,对应BitmapFactory.Options的outWidth和outHeight参数。

3.根据采样率的规则并结合目标View的所需大小,计算出采样率的取值。

4.将BitmapFactory.options的inJustDecodeBounds参数值设置为false,然后重新加载获取到缩小后的图片。

正常情况:

BitmapFactory获取图片的宽高也会按照drawable文件夹下的宽高设置来获取,所以获取到的结果也会不同,这一点我觉得几乎可以不做特别说明。

具体实现的代码如下:

/**
 *
 * @param res Resources
 * @param resId 资源Id
 * @param requestWidth 控件需要的实际宽度
 * @param requestHeight 控件需要的实际高度
 * @return
 */
public static Bitmap decodeSampledBitmapFromResource(Resources res,int resId,int requestWidth,int requestHeight){
    //1.将BitmapFactory.Options的inJustDecodeBounds参数值设置为true,并加载图片
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);
    //3.根据采样率的规则并结合目标View的所需大小,计算出采样率的取值。
    options.inSampleSize = calculateInSampleSize(options,requestWidth,requestHeight);
    //4.将BitmapFactory.options的inJustDecodeBounds参数值设置为false,然后重新加载获取到缩小后的图片。
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res,resId,options);
}

/**
 *
 * @param options BitmapFactory.Options
 * @param requestWidth 控件需要的实际宽度
 * @param requestHeight 控件需要的实际高度
 * @return
 */
private static int calculateInSampleSize(BitmapFactory.Options options, int requestWidth, int requestHeight) {
    //获取原始图片的宽和高
    final int width = options.outWidth;
    final int height = options.outHeight;
    //初始化采样率
    int inSampleSize = 1;
    if(width > requestWidth || height > requestHeight){
        final int halfWidth = height/2;
        final int halfHeight = width/2;
        //计算最适合的采样率
        while((halfWidth / inSampleSize) >= requestWidth && (halfHeight / inSampleSize) >= requestHeight){
            inSampleSize *= 2;
        }
    }
    return inSampleSize;
}
使用:

iv.setImageBitmap(decodeSampledBitmapFromResource(getResources(),R.id.imageView,100,100));

这种策略对于除了decodeStream方法外有点儿特殊,其他三种都适用,关于decodeStream的特殊在Cache的时候应该会提到,这一篇先记录这一点儿

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值