Android jpeglib 和 pnglib
作者:互联网
Androidstudio 编译jpeglib 和 pnglig的 so的简单记录
编译多个SO: 用ADD_SUBDIRECTORY 添加多个目录, 生产多个SO
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