·  阅读

图片为什么进行优化

内存消耗 流畅度 流量变小 apk包变小 用户体验 (资讯类)

加载框架优缺点:

1 Imageloader 多线程,支持下载监听 bitmap裁剪 列表暂停加载

2 Google =>glide 生命周期与activity一致,改变图片大小再加载到内存

3 facebook==>fresco 首次加载图片速度快 ,渐进式预览,多图请求, 支持webp格式,圆角图,对内存块图片进行了管理 使用共享内存机制

4 picasso == >缓存图片原图到本地 使用ARG888 内存占用大

图片oom的问题产生:

1 一个页面一次加载过多图片

2 加载大图片没有进行压缩(尺寸、质量)

3 android列表加载大量bitmap没有使用缓存

4 图片格式不合理 png无损失 建议webp格式

图片格式:

png:无损压缩的图片格式,占用空间大

jpeg:有损压缩,不支持透明

webp: 支持有损和无损压缩,首选

gif: 多帧动画 glide支持

图片存储优化:

1 使用webp替代png

2 压缩图片尺寸(采样率压缩)通过BintmapFactory.Options();inJustDecodeBounds = true;不会加载到内存,进而获取到图片的宽高,用来计算压缩比(insampleSize)

3 图片质量(解码率压缩)设置像素 RGB_565 字节只占两字节

4 内存重用 InBItmap

5 图片存入对应drawable,不然会生成不同大小的bitmap

图片加载优化:

1 图片放在xxhdpi 主流手机分辨率

2 在列表加载使用缓存 lrucache or (二级缓存: 内存(key-value) 文件 网络)

3 对图片懒加载,加载可视区域

4 bitmapRegionDecoder 在自定义View 重写 onMeasure onDraw onTouchEvent 绘画矩形区域

5 图片加载框架 glide fresco picasso

6 使用okhttp进行图片请求

bitmapRegionDecoder  局域清晰加载

1 重写view的onMeasure

2 ondraw() 获取bitmap

3 自定义view里实现ontouchevent 更新矩形区域

4 自定义view里实现GestureDetector的滑动监听onGestureListener 记录手指点下去的坐标

mipmap与drawable:

启动图片放mipmap,其他放入drwable,

兼容适配:

1 建立对应drwable文件,为每种dpi出一套图片资源

2 提供一套只要支持的最大dpi的图片,系统会自动渲染

影响Bitmap占用内存因素

  • 影响Bitmap占用内存的因素:
    • 图片最终加载的分辨率;
    • 图片的格式(PNG/JPEG/BMP/WebP);
    • 图片所存放的drawable目录;
    • 图片属性设置的色彩模式;
    • 设备的屏幕密度;

一个像素占用内存

  • 一个像素占用多大内存?Bitmap.Config用来描述图片的像素是怎么被存储的?
    • ARGB_8888: 每个像素4字节. 共32位,默认设置。
    • Alpha_8: 只保存透明度,共8位,1字节。
    • ARGB_4444: 共16位,2字节。
    • RGB_565:共16位,2字节,只存储RGB值。

Bitmap两种加载占用内存介绍

  • 网络 图片 计算Bitmap的内存大小
1 bitmap内存大小 = 图片长度 x 图片宽度 x 单位像素占用的字节数
起决定因素就是最后那个参数了,
2 Bitmap'常见有2种编码方式:ARGB_8888和RGB_565,ARGB_8888每个像素点4个byte,RGB_565是2个byte,一般都采用ARGB_8888这种。那么常见的1080*1920的图片内存占用就是:1920 x 1080 x 4 = 7.9M
3 width * height * 一个像素所占的内存;
  • 加载 本地资源 计算Bitmap的内存大小
nTargetDensity : 当前系统本身密度
inDensity默认为图片所在文件夹对应的密度
对资源文件: width * height * nTargetDensity/inDensity * nTargetDensity/inDensity * 一个像素所占的内存;

  • 使用API获取内存大小
  • getByteCount()  API12
    getAllocationByteCount()   API19之后
    区别:在复用Bitmap的情况下,getAllocationByteCount()可能会比getByteCount()大。

    图像加载的方式

    1 获取图像的来源一般有三种源头: 1.从网络加载2.从文件读取 3.从资源文件加载
    2 一般使用BitmapFactory的 decodeStream, decodeFile,decodeResource三个函数来获取到bitmap然后再调用ImageView的setImageBitmap 函数进行展现。



分类:
Android
标签: