其他分享
首页 > 其他分享> > Android jpeglib 和 pnglib

Android jpeglib 和 pnglib

作者:互联网

Androidstudio 编译jpeglib 和 pnglig的 so的简单记录

编译多个SO: 用ADD_SUBDIRECTORY 添加多个目录, 生产多个SO

 

 

#添加子目录,将自动找到子目录中的CMakeLists.txt ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/src/main/cpp/png) ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/src/main/cpp/jpeg)mylibrary/CMakeLists.txt    png 和 jpeg 目录下有源码和CMakeLists.txt 生产SO, 

cmake_minimum_required(VERSION 3.4.1)

#设置生成的so动态库最后输出的路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI})

#添加子目录,将自动找到子目录中的CMakeLists.txt
ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/src/main/cpp/png)
ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/src/main/cpp/jpeg)

 

 

测试libjpeg 和libpng:

可以从编译出来的aar中解压得到so

NativeFunc.java
public class NativeFunc {
    static { System.loadLibrary("native-lib"); }

    //测试libjpeg, 保存bitmap到/sdcard/image_test_save.jpeg
    public static native void saveJpeg(Bitmap bitmap);
    //测试libpng, 保存bitmap到/sdcard/image_test_save.png
    public static native void savePng(Bitmap bitmap);
}

//native-lib.cpp 

#include <jni.h>
#include <string>
#include <android/bitmap.h>
#include <android/log.h>
extern "C" {
#include "jpeg/jpeglib.h"
}
#include "png/png.h"

#define  LOG_TAG    "native_lib"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)


static void init_buffer(struct jpeg_compress_struct * c) {
}


static boolean empty_buffer(struct jpeg_compress_struct * compress_struct) {
    return TRUE;
}

static void term_buffer(struct jpeg_compress_struct * c) {
}

GLOBAL(void)
write_JPEG_Buff(uint8_t *buffPtr, int image_width, int image_height,
                JSAMPLE *imageBuffer, int resolution,  int *numCompBytes) {
    struct jpeg_error_mgr jerr;

    struct jpeg_compress_struct cinfo = {
            .client_data = NULL, .err = jpeg_std_error(&jerr)
    };

    jpeg_create_compress(&cinfo);
    struct jpeg_destination_mgr dm = {
            .init_destination = init_buffer, .empty_output_buffer = empty_buffer,
            .term_destination = term_buffer, .next_output_byte = buffPtr,
            .free_in_buffer = (size_t) image_width * image_height * 3
    };
    cinfo.dest = &dm;
    cinfo.image_width = (JDIMENSION) image_width;
    cinfo.image_height = (JDIMENSION) image_height;

    cinfo.in_color_space = JCS_EXT_RGBA;
    cinfo.jpeg_color_space = JCS_EXT_RGBA;
    cinfo.input_components = 4;


    jpeg_set_defaults(&cinfo);

    jpeg_set_quality(&cinfo, 95, TRUE); // TRUE = limit to baseline-JPEG values
    cinfo.MCUs_per_row = (JDIMENSION) image_width;
    cinfo.MCU_rows_in_scan = (JDIMENSION) image_height;

    jpeg_start_compress(&cinfo, TRUE);

    int row_stride; // physical row width in image buffer
    row_stride = image_width * cinfo.input_components; // JSAMPLEs per row in imageBuffer

    JSAMPROW row_pointer[1]; // pointer to JSAMPLE row[s]
    while (cinfo.next_scanline < cinfo.image_height) {
        row_pointer[0] = &imageBuffer[cinfo.next_scanline * row_stride];
        (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
    }

    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);
    *numCompBytes = (int) (cinfo.dest->next_output_byte - buffPtr);
}

//测试libjpeg, 保存bitmap到/sdcard/image_test_save.jpeg
extern "C" JNIEXPORT void JNICALL
Java_com_lightin_imagedemo_NativeFunc_saveJpeg(
        JNIEnv *env,
        jclass type, /* this */
        jobject bitmap) {
    AndroidBitmapInfo  info;
    int ret;
    int width = 0;
    int height = 0;
    void*              pixels;
    if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {
        LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
        return;
    }
    width = info.width;
    height = info.height;

    if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
        LOGE("Bitmap format is not RGBA_8888 !");
        return;
    }

    if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) {
        LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
    }

    char fileName[100];
    sprintf(fileName,"/sdcard/image_test_save.jpeg");
    FILE *file;
    file = fopen(fileName, "wb");
    int *ybuf = (int *)malloc(sizeof(int) * (width*height));
    int outSize;

    write_JPEG_Buff((uint8_t*)ybuf,width,height,(JSAMPLE *)pixels,0, &outSize);

    fwrite((unsigned char *)ybuf, outSize, 1, file);
    fclose(file);

    if(ybuf) free(ybuf);

    AndroidBitmap_unlockPixels(env, bitmap);

}


int writePng(char* png_file_name, unsigned char*  pixels , int width, int height, int bit_depth){

    png_structp png_ptr;

    png_infop info_ptr;

    FILE *png_file = fopen(png_file_name, "wb");


    if (!png_file)
    {
        return -1;
    }
    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if(png_ptr == NULL)
    {
        printf("ERROR:png_create_write_struct/n");
        fclose(png_file);
        return 0;
    }
    info_ptr = png_create_info_struct(png_ptr);
    if(info_ptr == NULL)
    {
        printf("ERROR:png_create_info_struct/n");
        png_destroy_write_struct(&png_ptr, NULL);
        return 0;
    }
    png_init_io(png_ptr, png_file);
    png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_RGB_ALPHA,
                 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);


    png_colorp palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH * sizeof(png_color));
    if (!palette) {
        fclose(png_file);
        png_destroy_write_struct(&png_ptr, &info_ptr);
        return false;
    }
    png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH);
    png_write_info(png_ptr, info_ptr);
    png_set_packing(png_ptr);
    //这里就是图像数据了
    png_bytepp rows = (png_bytepp)png_malloc(png_ptr, height * sizeof(png_bytep));
    for (int i = 0; i < height; ++i)
    {
        rows[i] = (png_bytep)(pixels + (i) * width*4 );
    }

    png_write_image(png_ptr, rows);
    delete[] rows;
    png_write_end(png_ptr, info_ptr);
    png_free(png_ptr, palette);
    palette=NULL;
    png_destroy_write_struct(&png_ptr, &info_ptr);
    fclose(png_file);

    return 0;
}

//测试libpng, 保存bitmap到/sdcard/image_test_save.png
extern "C" JNIEXPORT void JNICALL
Java_com_lightin_imagedemo_NativeFunc_savePng(
        JNIEnv *env,
        jclass type/* this */,
        jobject bitmap) {

    AndroidBitmapInfo  info;
    int ret;
    int width = 0;
    int height = 0;
    void*              pixels;
    if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {
        LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
        return;
    }
    width = info.width;
    height = info.height;

    if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
        LOGE("Bitmap format is not RGBA_8888 !");
        return;
    }

    if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) {
        LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
    }

    char fileName[100];
    sprintf(fileName,"/sdcard/image_test_save.png");

    writePng(fileName,( unsigned char*)pixels,width,height,8);

    AndroidBitmap_unlockPixels(env, bitmap);

}

 

标签:info,int,pnglib,jpeg,cinfo,jpeglib,Android,ptr,png
来源: https://blog.csdn.net/weixin_42065195/article/details/104922538