Bitmap的高效加载(Android开发艺术探索学习笔记)

来源:互联网 发布:腾讯云阿里云哪个好 编辑:程序博客网 时间:2024/05/24 02:20

概述

如何高效地加载Bitmap?其实核心思想很简单,那就是采用BitmapFactory.Options加载所需尺寸的图片。有时候我们用ImageView加载图片,图片的原始尺寸远远大于ImageView。这个时候把图片完全加载进来没有必要,因为ImageView也显示不出来原始的图片。

我们可以使用BitmapFactory.Options对图片进行预加载,然后对图片进行压缩,将缩小后的图片放在ImageView中展示。这样提高了Bitmap加载的性能,一定程度上避免了OOM。

BitmapFactory提供了四类方法加载图片:

  1. decodeFile(),从文件系统加载。
  2. decodeResource(),资源文件中加载。
  3. decodeStream(),从输入流加载。
  4. decodeByteArray(),从字节数组中加载。

注意:查看源码可以发现,decodeFile()decodeResource()间接调用decodeStream()

inSampleSize

下面我们来介绍inSampleSize这个参数,当这个参数为1时,采样后的图片大小和原来一样;当这个参数为2时,采样后的图片宽高均为原来的1/2,大小也就成了原来的1/4。也就是说,采样后的大小等于原始大小除以采样率的平方

  • 官方文档规定,inSampleSize的值应为2的非负整数次幂(1,2,4,… ),否则会被系统向下取整并找到一个最接近的值。

通过设置inSampleSize我们就能够将图片缩放到一个合理的大小,那么该如何设置inSampleSize的值呢?

在讲解这个之前,我们先来考虑以下情况:我们的ImageView的大小为100 * 100,要显示的图片大小为300 * 400,此时我们应该将inSampleSize设为多少呢

首先我们通过计算可以得到图片宽是ImageView的3倍,而图片高是ImageView的4倍。那么我们应该将图片宽高缩小为原来的4倍吗?假如我们把图片宽高都变为原来的1/4,那么现在图片大小为75 * 100,ImageView大小为100 * 100,图片要显示在ImageView中需要进行拉伸,而拉伸的话可能会导致图片失真。所以我们应该把图片宽高变为原来的1/3,以保证它不小于ImageView的大小,这样尽管多占用一些内存,但不会造成图片质量的下降,这还是很有必要的。

通过以上分析,我们知道了在设置inSampleSize时应该注意使得缩放后的图片大小不小于相应的ImageView大小

计算inSampleSize的步骤

1.获取图片的原始宽高,通过将Options的inJustDecodeBounds属性设为true后调用decodeResource方法,可以实现不真正加载图片而只是获取图片的尺寸信息,请看以下代码:

BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeResource(getResources(), resId, options);//现在原始宽高以存储在了options对象的outWidth和outHeight实例域中

2.根据原始宽高计算出inSampleSize,代码如下:

    //dstWidth和dstHeight分别为目标ImageView的宽高    public static int calSampleSize(BitmapFactory.Options options, int dstWidth, int dstHeight) {        int rawWidth = options.outWidth;        int rawHeight = options.outHeight;        int inSampleSize = 1;        if (rawWidth > dstWidth || rawHeight > dstHeight) {            float ratioHeight = (float) rawHeight / dstHeight;            float ratioWidth = (float) rawWidth / dstHeight;            inSampleSize = (int) Math.min(ratioWidth, ratioHeight);        }        return inSampleSize;    }

以上代码的逻辑很直接,唯一需要注意的就是要记得使采样后的图片能够“覆盖”ImageView,以防止图片质量下降。

参考:Android开发之高效加载Bitmap

阅读全文
0 0
原创粉丝点击