Bitmap 相关的面试点

1:基础知识

注:这里inDensity表示目标图片的dpi(放在哪个资源文件夹下),inTargetDensity表示目标屏幕的dpi,所以你可以发现inDensity和inTargetDensity会对Bitmap的宽高 进行拉伸,进而改变Bitmap占用内存的大小。

ARGB_8888/RGB_565

  • ARGB_8888占内存、清晰度高、支持透明效果
  • RGB_565节省内存、清晰度适中、不支持透明效果

枚举变量

public static final Bitmap.Config ALPHA_8
public static final Bitmap.Config ARGB_4444
public static final Bitmap.Config ARGB_8888
public static final Bitmap.Config RGB_565

Bitmap.Config ARGB_4444:// 每个像素占四位,即A=4,R=4,G=4,B=4,那么一个像素点占4+4+4+4=16位
Bitmap.Config ARGB_8888:// 每个像素占四位,即A=8,R=8,G=8,B=8,那么一个像素点占8+8+8+8=32位
Bitmap.Config RGB_565: // 每个像素占四位,即R=5,G=6,B=5,没有透明度,那么一个像素点占5+6+5=16位
Bitmap.Config ALPHA_8: // 每个像素占四位,只保存透明度,不保存颜色。
复制代码

使用要领

由于ARGB_4444不推荐使用和ALPHA_8效果不明。我们大多数是用的还是ARGB_8888和RGB_565。 RGB_565能够在保证图片质量的情况下大大减少内存的开销,是解决oom的一种方法。**但是一定要注意RGB_565是没有透明度的,**如果图片本身需要保留透明度,那么就不能使用RGB_565。

如何计算 Bitmap 占用内存的大小

  • Bitamp 占用内存大小 = 宽度像素 x (inTargetDensity / inDensity) x 高度像素 x (inTargetDensity / inDensity)x 一个像素所占的内存

获取内存占用大小的方法

  • getByteCount():API12 加入,代表存储 Bitmap 的像素需要的最少内存。
  • getAllocationByteCount():API19 加入,代表在内存中为 Bitmap 分配的内存大小,代替了 getByteCount() 方法。

合理的利用 API,使用Bitmap 更安全

  • BitmapFactory.Options.inPreferredConfig:将ARGB_8888改为RGB_565,改变编码方式,节约内存。
  • BitmapFactory.Options.inSampleSize:缩放比例,可以参考Luban那个库,根据图片宽高计算出合适的缩放比例。
  • BitmapFactory.Options.inPurgeable:让系统可以内存不足时回收内存。

2:如何在不压缩的情况下加载高清大图?

  • 使用 BitmapRegionDecoder

    • setInputStream 里面去获得图片的真实的宽度和高度,以及初始化我们的mDecoder

    • onMeasure 里面为我们的显示区域的rect赋值,大小为view的尺寸

    • onTouchEvent 里面我们监听move的手势,在监听的回调里面去改变rect的参数,以及做边界检查,最后invalidate

    • onDraw 里面就是根据rect拿到bitmap,然后draw了

猜你喜欢

转载自juejin.im/post/6983624900237852709