Android 性能优化 03---Bitmap优化02(huf

2022-04-01  本文已影响0人  沪漂意哥哥

一.理论基础

android 使用Skia图像处理引擎,skia引擎基于jpeg引擎二次开发而来(类似于retrofit 与okhttp的关系)。jpeg引擎提供两种图片压缩编码(普通优化编码和哈夫曼编码)
注意:android 7.0 Skia引擎写死了是普通优化编码,在7.0以后,才可以选择哈夫曼编码。

二.哈夫曼编码

可变长编码(节约内存),根据频率越高,位数越短。

三.效果对比

image.png

四.代码

 public void onLoad(View view) {
        File input = new File(Environment.getExternalStorageDirectory()
                , "main.jpg");

        Bitmap inputBitmap = BitmapFactory.decodeFile(input.getAbsolutePath());
        File output= new File(Environment.getExternalStorageDirectory(),

                "微信压缩.jpg");

        compress(inputBitmap, output.getAbsolutePath());
    }
typedef uint8_t BYTE;
extern "C"{
#include "jpeglib.h"
}

//jpeg  引擎
void writeImg(BYTE *data, const char *path, int w, int h) {
    struct jpeg_compress_struct jpeg_struct;
    jpeg_error_mgr err;
    jpeg_struct.err= jpeg_std_error(&err);
    jpeg_create_compress(&jpeg_struct);
    FILE *file = fopen(path, "wb");
    jpeg_stdio_dest(&jpeg_struct, file);
    jpeg_struct.image_width = w;
    jpeg_struct.image_height = h;
    jpeg_struct.input_components = 3;
    jpeg_struct.in_color_space = JCS_RGB;

    //核心 /* TRUE=arithmetic coding, FALSE=Huffman */
    jpeg_struct.arith_code = FALSE;

    jpeg_set_defaults(&jpeg_struct);
    jpeg_set_quality(&jpeg_struct, 30, true);

    //开启压缩
    jpeg_start_compress(&jpeg_struct, TRUE);

    JSAMPROW row_pointer[1];
    while (jpeg_struct.next_scanline < h) {
        row_pointer[0]= &data[jpeg_struct.next_scanline * w * 3];
        jpeg_write_scanlines(&jpeg_struct,row_pointer,1);
    }
    jpeg_finish_compress(&jpeg_struct);
    fclose(file);
    jpeg_destroy_compress(&jpeg_struct);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_luisliuyi_demo_optimize_bitmap02_MainActivity_compress(JNIEnv *env, jobject thiz,
                                                                jobject bitmap,
                                                                jstring path_) {
    const char *path = env->GetStringUTFChars(path_, 0);
    AndroidBitmapInfo bitmapInfo;
    AndroidBitmap_getInfo(env, bitmap, &bitmapInfo);
    int h = bitmapInfo.height;
    int w = bitmapInfo.width;
    BYTE *pixels;
    AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void **>(&pixels));
    BYTE *data,*tmpData;
    data = static_cast<BYTE *>(malloc(w * h * 3));
    tmpData = data;
    BYTE a, r, g, b;
    int color;
    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            color = *((int *) pixels);
            a = ((color & 0xFF000000) >> 16);
            r = ((color & 0x00FF0000) >> 16);
            g = ((color & 0x0000FF00) >> 8);
            b = (color & 0x000000FF);
            *data = b;
            *(data + 1) = g;
            *(data + 2) = r;
            data += 3;
            pixels += 4;
        }
    }
    writeImg(tmpData, path, w, h);
    AndroidBitmap_unlockPixels(env, bitmap);
    env->ReleaseStringUTFChars(path_, path);
}

五.结果

image.png

六.代码地址

https://gitee.com/luisliuyi/android-optimize-bitmap02.git
上一篇 下一篇

猜你喜欢

热点阅读