高效加载 Bitmap

来源:互联网 发布:计算微积分的软件 编辑:程序博客网 时间:2024/05/17 23:44

在翻阅了 Universal-ImageLoader 源码之后,现在来总结一下如何高效加载 Bitmap 。在 Android 应用我们经常会看到使用 ListView 去加载大量的图片,而如果没有合理去加载 Bitmap 是很容易就造成内存溢出的。

举个例子

假如 ImageView 大小: 200*400

  • 需要加载的图片大小 1080*1920
    这样要把这么大的图片加载到 ImageView 上就完全没有必要了,而且很容易 oom

  • 假如图片采用 ARGB8888 格式存储的话,那么一个像素就占用了 4 个字节
    1080*1920*4 = 7.9m 也就是说加载这么一张图片需要 7.9m 的空间。

压缩图片有四种方式:

   BitmapFactory.decodeFile:针对文件系统   BitmapFactory.decodeResource:针对资源文件   BitmapFactory.decodeByteArray:针对字节数组   BitmapFactory.decodeStream:针对输入流

Bitmap 的高效加载其核心就是对需要加载图片进行压缩,使用 BitmapFactory.Option 来加载指定大小的图片。

操作步骤:

  • options.inJustDecodeBounds = true;
    设置该标记未 true 表示只加载 bitmap 的大小信息,并不会将整个 Bitmap 加载到内存中
  • BitmapFactory.decodeXX(options)
  • 根据得到的 options 计算 inSampleSize
    注意:官方推荐这里的 inSampleSize 应该为 2 指数倍。
  • options.inJustDecodeBounds = false;
    设置该标记为 false 表示将 Bitamo 真正加载到内存中。
  • Bitmap bmp = BitmapFactory.decodeXX(options)

示例代码

BitmapFactory.Options opts = new BitmapFactory.Options();opts.inJustDecodeBounds = true;BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher, opts);//计算 inSampleSizeopts.inSampleSize = calculateInSampleSize(opts, 300, 300);//加载 Bitmap 到内存中opts.inJustDecodeBounds = false;bmp = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher, opts);//加载一张 Bitmap 显示在 ImageViewmImageView.setImageBitap(bmp)/** * 计算 inSampleSize * * @param opts * @param reqWidth * @param reqHeight * @return */private int calculateInSampleSize(BitmapFactory.Options opts, int reqWidth, int reqHeight) {    int inSampleSize = 1;    final int width = opts.outWidth;    final int height = opts.outHeight;    if (height > reqHeight || width > reqWidth) {        final int halfWidth = width / 2;        final int halfHeight = height / 2;        //500*800 1        //250*400 2        //125*200 4 不成立,最后 inSampleSize = 4        while (halfHeight / inSampleSize >= reqHeight && halfWidth / inSampleSize >= reqWidth) {            inSampleSize *= 2;        }    }    return inSampleSize;}
原创粉丝点击