}
从上述代码中,我们看到bitmap最终通过canvas绘制出来,而canvas在绘制之前,有一个scale的操作,scale的值由
scale = (float) targetDensity / density;
这一行代码决定,即缩放的倍率和targetDensity和density相关,而这两个参数都是从传入的options中获取到的。这时候,需要回到Java层,看看options这个对象的定义和赋值。
BitmapFactory#Options
Options是BitmapFactory中的一个静态内部类,用于配置Bitmap在decode时的一些参数。
// native层doDecode方法,传入了Options参数
static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding, jobject options)
其内部有很多可配置的参数,下面的类图,列举出了部分常用的参数。
我们先关注之前提到的几个密度相关的参数,通过阅读源码的注释,大概可以知道这三个密度参数代表的涵义:
-
inDensity:Bitmap位图自身的密度、分辨率
-
inTargetDensity: Bitmap最终绘制的目标位置的分辨率
-
inScreenDensity: 设备屏幕分辨率
其中inDensity和图片存放的资源文件的目录有关,同一张图片放置在不同目录下会有不同的值:
| density | 0.75 | 1 | 1.5 | 2 | 3 | 3.5 | 4 |
| — | — | — | — | — | — | — | — |
| densityDpi | 120 | 160 | 240 | 320 | 480 | 560 | 640 |
| DpiFolder | ldpi | mdpi | hdpi | xhdpi | xxhdpi | xxxhdpi | xxxxhdpi |
inTargetDensity和inScreenDensity一般来说,很少手动去赋值,默认情况下,是和设备分辨率保持一致。为此,我在手机(红米4,Android 6.0系统,设备dpi 480)上测试加载不同资源文件下的bitmap的参数,结果见下图:
以上可以验证几个结论:
-
同一张图片,放在不同资源目录下,其分辨率会有变化,
-
bitmap分辨率越高,其解析后的宽高越小,甚至会小于图片原有的尺寸(即缩放),从而内存占用也相应减少
-
图片不特别放置任何资源目录时,其默认使用mdpi分辨率:160