Bitmap优化1:
Bitmap在内存中创建过程
Bitmap bm = nativeCreate(null, 0, width, width, height, config.nativeInt, mutable, xyzD50, p);
// Bitmap.cpp L713
static jobject Bitmap_creator() {
SkBitmap bitmap; // 相当于new了个SkBitmap对象
// 给图片设置值:宽高,colorType
bitmap.setInfo(SkImageInfo::Make(width,height,colorType, kPremul_SkAlphaType, colorSpace));
sk_sp<Bitmap> nativeBitmap= Bitmap::allocateHeapBitmap(&bitmap, NULL);
}
nativeBitmap=Bitmap::allocateHeapBitmap(bitma.get(), ctable);
return createBitmap(env, nativeBitmap.release(),
getPremulBitmapCreateFlags(isMutale), NULL, NULL, density);
在native区,创建图片对象(又宽高信息等)。此图片对象,被skBitmap所指向。skBitmap的引用,会以参数的形式传递到java。
private final long mNativePtr;// java层找不到这个内存,但是又能操作这个内存。如压缩,获取宽高等。
所有的native函数,都需要这个long类型的mNativePtr。
内存分析
app内存划区-java:
- 方法区 code
- 堆区
- 栈区
- Graphic: opengl,GPU内存。
app内存划分-native:
- 图片
Bitmap底层渲染。
extern "c"
Java_com_maniu_bitmapmaniu_ImageHandler_updateFrame(JNIEnv *env, jobject thiz, jobject bitmap) {
AndroidBitmapInfo info;
int *pixels = NULL; // 指向naive层的图片内存区。
AndroidBitmap_getInfo(env, bitmap, &info);
// CMakeList.txt中 的target_link_libraries添加:jnigraphics
AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void **>(&pixels)); // 锁住内存
// pixels[0] = 0xFF0000; // 第一个点修改红色
int width = info.width;
int height = info.height;
int *px = pixels;
int *line;
for(int y=0; y<height; y++) { // 一行行的遍历。
line = px;
for(int x=0; x<width; x++){
line[x] = 0xFFFF0000; // 内存区赋值。
}
// 切换到下一行, stride一行的字节数。(width = info.stride/4),一个像素有4个字节。
px = px + width;
}
// 解锁
AndroidBitmap_unlockPixels(env, bitmap);
}
Bitmap复用的前提条件。
手写案例实现bitmap,渲染gif。
Bitmap使用的是java内存,还是native内存?
------native内存。
Bitmap直接在渲染引擎,native层,而不是java层,避免通信。
可以在native直接显示渲染。绘制最快,性能最高。
Gif加载:android-gif-drawable
系统源码(external/giflib)
gif的 LZW压缩,将所有像素汇总到一张表里面。