阅读 60

Bitmap

选择合适的图片规格

  • ALPHA_8           每个像素占用1byte内存
  • ARGB_4444      每个像素占用2byte内存
  • ARGB_8888      每个像素占用4byte内存(默认)
  • RGB_565           每个像素占用2byte内存

质量压缩

不会对内存产生影响,在保持像素的前提下改变图片的位深及透明度等,来达到压缩图片的目的,这样适合去传递二进制的图片数据,比如分享图片,要传入二进制数据过去,限制500kb之内。

降低采样率

原理

采样率压缩是改变了图片的像素,他是通过先读取图片的边,然后在自己设定图片的边,然后根据设定,读取图片的像素。在读取的时候,并不是所有的像素都读取,而是由选择的。

例如:一张1024 ×1024像素的图片,采用ARGB8888格式存储,那么内存大小1024×1024×4=4M。如果inSampleSize=2,那么采样后的图片内存大小:512×512×4=1M。

注意:官方文档支出,inSampleSize的取值应该总是2的指数,如1,2,4,8等。如果外界传入的inSampleSize的值不为2的指数,那么系统会向下取整并选择一个最接近2的指数来代替。比如3,系统会选择2来代替。当时经验证明并非在所有Android版本上都成立。

采样率压缩过程

  1. 将BitmapFactory.Options的inJustDecodeBounds参数设为true并加载图片。
  2. 从BitmapFactory.Options中取出图片的原始宽高信息,它们对应于outWidth和outHeight参数。
  3. 根据采样率的规则并结合目标View的所需大小计算出采样率inSampleSize。
  4. 将BitmapFactory.Options的inJustDecodeBounds参数设为false,然后重新加载图片。

复用内存

@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private void initBitmap() {
    BitmapFactory.Options options = new BitmapFactory.Options();
    // 图片复用,这个属性必须设置;
    options.inMutable = true;
    // 手动设置缩放比例,使其取整数,方便计算、观察数据;
    options.inDensity = 320;
    options.inTargetDensity = 320;
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg_autumn_tree_min, options);
    // 对象内存地址;
    Log.i("ycBitmap", "bitmap = " + bitmap);
    Log.i("ycBitmap", "ByteCount = " + bitmap.getByteCount() + ":::bitmap:AllocationByteCount = " + bitmap.getAllocationByteCount());
    // 使用inBitmap属性,这个属性必须设置;
    options.inBitmap = bitmap; options.inDensity = 320;
    // 设置缩放宽高为原始宽高一半;
    options.inTargetDensity = 160;
    options.inMutable = true;
    Bitmap bitmapReuse = BitmapFactory.decodeResource(getResources(), R.drawable.bg_kites_min, options);
    // 复用对象的内存地址;
    Log.i("ycBitmap", "bitmapReuse = " + bitmapReuse);
    Log.i("ycBitmap", "bitmap:ByteCount = " + bitmap.getByteCount() + ":::bitmap:AllocationByteCount = " + bitmap.getAllocationByteCount());
    Log.i("ycBitmap", "bitmapReuse:ByteCount = " + bitmapReuse.getByteCount() + ":::bitmapReuse:AllocationByteCount = " + bitmapReuse.getAllocationByteCount());

    //11-26 18:24:07.971 15470-15470/com.yc.cn.ycbanner I/ycBitmap: bitmap = android.graphics.Bitmap@9739bff
    //11-26 18:24:07.972 15470-15470/com.yc.cn.ycbanner I/ycBitmap: bitmap:ByteCount = 4346880:::bitmap:AllocationByteCount = 4346880
    //11-26 18:24:07.994 15470-15470/com.yc.cn.ycbanner I/ycBitmap: bitmapReuse = android.graphics.Bitmap@9739bff
    //11-26 18:24:07.994 15470-15470/com.yc.cn.ycbanner I/ycBitmap: bitmap:ByteCount = 1228800:::bitmap:AllocationByteCount = 4346880
    //11-26 18:24:07.994 15470-15470/com.yc.cn.ycbanner I/ycBitmap: bitmapReuse:ByteCount = 1228800:::bitmapReuse:AllocationByteCount = 4346880
}
复制代码

使用recycle()方法及时回收内存

参考:

Android性能优化(五)之细说Bitmap

彻底理解Bitmap的高效加载策略

Bitmap的压缩方式

Android Bitmap的常用压缩方式

文章分类
Android
文章标签