【Android】Bitmap优化

Bitmap decode

  • 常见的图像存储格式:jpg,png,webp
  • Android中显示图片必须要先经过解码(decode)读取图像的数据到内存中
  • BitmapFactory提供了常用的一些decode方法
  • 图片真正占用的内存大小要看decode之后的数据大小。用字节数组的方式存储。

Bitmap memory

  • <= 2.3.3(api 10) Bitmap解码之后的数据存储在NativeMemory中,手动调用Recycle回收
  • =3.0 (api 11) Bitmap解码之后的数据存储在Dalvik heap中,由Dalvik自动回收

Re-using Bitmaps

大量Bitmap的创建和垃圾回收,会产生内存抖动,引发卡顿。

对象池:内存缓冲区,系统启动时,预先向JVM申请一块内存,用来构建多个对象。用完后从池里找空闲对象用,避免频繁创建新对象。

SDK19+ ,复用条件:

  • 宽高因素:之前的Bitmap空间要大于想要创建的Bitmap,才能复用。只能把小图放到大图里。
  • 像素格式:一个像素需要多少字节存储该像素的信息。常见的有:565,4444,8888。两者像素格式要相同才能复用。可以把对象池按照像素格式分类。

优秀的第三方库:glide,里面封装了良好的对象池的管理。

Pre-scaling Bitmap

有一张巨大的图,但我们想显示的图不需要原始图片那么大。进行图片压缩。

createScaledBitmap(inBmp, 64, 128);

这个API不好,它是把内存中的一张大图,压缩成一幅小图,此时大图已经进入内存了,不够理想。下面的方法更好,是采样的方法将小图加载到内存中。

mBitmapOption.inSampleSize = 4;  加载的图片变成原图的1/4。
mCurrentBitmap = BitmapFactory.decodeFile(fileName, mBitmapOptions);

上面如果写的9,系统会把这个9变成最近的2的n次方整数8。如果想以任意倍数抽样,可以用下面的方式:

mBitmapOption.inScaled = true;
mBitmapOption.inDensity = srcWidth;
mBitmapOption.inTargetDensity = dstWidth;

mCurrentBitmap = BitmapFactory.decodeResources(getResources(), mImageIDs, mBitmapOptions);

bitmapfactory.cpp:

if(inScaled){
	if(inDensity != 0 && inTargetDensity != 0 && inDensity != inScreenDensity){
		scale = (float) inTargetDensity / inDensity;
	}
}

往往会把上面两个步骤合起来做,先按2的n次方缩小一波,在得到的小图基础上,再按自由比例缩小一波,非常省时间:

mBitmapOption.inScaled = true;
mBitmapOption.inSampleSize = 4;  加载的图片变成原图的1/4
mBitmapOption.inDensity = srcWidth;
mBitmapOption.inTargetDensity = dstWidth * mBitmapOptions.inSampleSize;
mCurrentBitmap = BitmapFactory.decodeFile(fileName, mBitmapOptions);

如何获取原图的宽和高?在不加载图片的前提下。

MBitmapOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fileName, mBitmapOptions);
srcWidth = mBitmapOptions.outWidth;
srcHeight = mBitmapOptions.outHeight;

Smaller Pixel Format 更小的像素格式

FormatBits Per Pixel备注
ARGB_888832支持透明度,质量较高,占用内存大
RGB_56516不支持透明度,质量比8888低很多,适合大图
ARGB_444416对图片质量要求不高,又想支持透明度,可用
ALPHA_88只有透明度时

下面是两种选择,如果更珍惜内存,那么选用下面的组合方式可以节省很多内存;如果更珍惜CPU资源,那么选用上面的单个8888格式图片能减少CPU的二次渲染。
在这里插入图片描述

Smaller PNG files

可以用 Script PNG 对 PNG 图片进行压缩。

web p格式的图片是GOOGLE优化的图片格式,既支持透明度也支持丰富的颜色,体积和质量都好,Picasso图片库支持转换成Web P格式的图片。

LRU Cache

可以用LRU Cache实现对象池。
当要从缓存删除一个条目时,删除最近最少使用的那个。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值