目录
一 应用层Bitmap的创建方式
1.构造函数
frameworks/base/graphics/java/android/graphics/Bitmap.java
/**
* Private constructor that must receive an already allocated native bitmap
* int (pointer).
*/
// JNI now calls the version below this one. This is preserved due to UnsupportedAppUsage.
@UnsupportedAppUsage(maxTargetSdk = 28)
Bitmap(long nativeBitmap, int width, int height, int density,
boolean requestPremultiplied, byte[] ninePatchChunk,
NinePatch.InsetStruct ninePatchInsets) {
this(nativeBitmap, width, height, density, requestPremultiplied, ninePatchChunk,
ninePatchInsets, true);
}
// called from JNI and Bitmap_Delegate.
Bitmap(long nativeBitmap, int width, int height, int density,
boolean requestPremultiplied, byte[] ninePatchChunk,
NinePatch.InsetStruct ninePatchInsets, boolean fromMalloc) {
}
可以看到它只接受JNI或者bitmap代理调用,不允许应用new它。
2.Bitmap静态方法创建
方法很多,不过最终调用到的都是
Bitmap bm = nativeCreate(null, 0, width, width, height, config.nativeInt, true,
colorSpace == null ? 0 : colorSpace.getNativeInstance());
3.BitmapFactory创建
我们这里跟一下BitmapFactory的Bitmap创建流程
frameworks/base/graphics/java/android/graphics/BitmapFactory.java
public static Bitmap decodeResource(Resources res, int id, Options opts) {
validate(opts);
Bitmap bm = null;
InputStream is = null;
...
final TypedValue value = new TypedValue();
is = res.openRawResource(id, value);
bm = decodeResourceStream(res, value, is, null, opts);
...
return bm;
}
@Nullable
public static Bitmap decodeResourceStream(@Nullable Resources res, @Nullable TypedValue value,
@Nullable InputStream is, @Nullable Rect pad, @Nullable Options opts) {
validate(opts);
if (opts == null) {
opts = new Options();
}
if (opts.inDensity == 0 && value != null) {
final int density = value.density;
if (density == TypedValue.DENSITY_DEFAULT) {
opts.inDensity = DisplayMetrics.DENSITY_DEFAULT;
} else if (density != TypedValue.DENSITY_NONE) {
//这里density的值如果对应资源目录为hdpi的话,就是240
opts.inDensity = density;
}
}
//当前屏幕显示密度,我的oppo手机是480
if (opts.inTargetDensity == 0 && res != null) {
opts.inTargetDensity = res.getDisplayMetrics().densityDpi;
}
return decodeStream(is, pad, opts);
}
这里的重点是opts.inDensity 和opts.inTargetDensity,我们需要根据当前的density进行图片的压缩。我们接着往下看就到了native层
/**
* Private helper function for decoding an InputStream natively. Buffers the input enough to
* do a rewind as needed, and supplies temporary storage if necessary. is MUST NOT be null.
*/
private static Bitmap decodeStreamInternal(@NonNull InputStream is,
@Nullable Rect outPadding, @Nullable Options opts) {
// ASSERT(is !