安卓NDK开发-实现图片的高效压缩
来源:互联网 发布:企业数据安全 编辑:程序博客网 时间:2024/05/23 17:06
1、将Android的bitmap解码并转换为RGB数据
2、为JPEG对象分配空间并初始化
3、指定压缩数据源
4、获取文件信息
5、为压缩设定参数,包括图像大小,颜色空间
6、开始压缩
7、压缩完毕
8、释放资源
2、为JPEG对象分配空间并初始化
3、指定压缩数据源
4、获取文件信息
5、为压缩设定参数,包括图像大小,颜色空间
6、开始压缩
7、压缩完毕
8、释放资源
#include <string.h>#include <android/bitmap.h>#include <android/log.h>#include <jni.h>#include <stdio.h>#include <setjmp.h>#include <math.h>#include <stdint.h>#include <time.h>#include "jpeglib.h"#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */#include "jversion.h" /* for version message */#include "config.h"#define LOG_TAG "jni"#define LOGW(...) __android_log_write(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)#define true 1#define false 0typedef uint8_t BYTE;char *error;struct my_error_mgr { struct jpeg_error_mgr pub; jmp_buf setjmp_buffer;};typedef struct my_error_mgr * my_error_ptr;METHODDEF(void)my_error_exit (j_common_ptr cinfo){ my_error_ptr myerr = (my_error_ptr) cinfo->err; (*cinfo->err->output_message) (cinfo); error=myerr->pub.jpeg_message_table[myerr->pub.msg_code]; LOGE("jpeg_message_table[%d]:%s", myerr->pub.msg_code,myerr->pub.jpeg_message_table[myerr->pub.msg_code]); // LOGE("addon_message_table:%s", myerr->pub.addon_message_table);// LOGE("SIZEOF:%d",myerr->pub.msg_parm.i[0]);// LOGE("sizeof:%d",myerr->pub.msg_parm.i[1]); longjmp(myerr->setjmp_buffer, 1);}//图片压缩方法int generateJPEG(BYTE* data, int w, int h, int quality, const char* outfilename, jboolean optimize) { int nComponent = 3; struct jpeg_compress_struct jcs; struct my_error_mgr jem; jcs.err = jpeg_std_error(&jem.pub); jem.pub.error_exit = my_error_exit; if (setjmp(jem.setjmp_buffer)) { return 0; } //为JPEG对象分配空间并初始化 jpeg_create_compress(&jcs); //获取文件信息 FILE* f = fopen(outfilename, "wb"); if (f == NULL) { return 0; } //指定压缩数据源 jpeg_stdio_dest(&jcs, f); jcs.image_width = w; jcs.image_height = h; if (optimize) { LOGI("optimize==ture"); } else { LOGI("optimize==false"); } jcs.arith_code = false; jcs.input_components = nComponent; if (nComponent == 1) jcs.in_color_space = JCS_GRAYSCALE; else jcs.in_color_space = JCS_RGB; jpeg_set_defaults(&jcs); jcs.optimize_coding = optimize; //为压缩设定参数,包括图像大小,颜色空间 jpeg_set_quality(&jcs, quality, true); //开始压缩 jpeg_start_compress(&jcs, TRUE); JSAMPROW row_pointer[1]; int row_stride; row_stride = jcs.image_width * nComponent; while (jcs.next_scanline < jcs.image_height) { row_pointer[0] = &data[jcs.next_scanline * row_stride]; //写入数据 jpeg_write_scanlines(&jcs, row_pointer, 1); } if (jcs.optimize_coding) { LOGI("optimize==ture"); } else { LOGI("optimize==false"); } //压缩完毕 jpeg_finish_compress(&jcs); //释放资源 jpeg_destroy_compress(&jcs); fclose(f); return 1;}typedef struct { uint8_t r; uint8_t g; uint8_t b;} rgb;//将java string转换为char*char* jstrinTostring(JNIEnv* env, jbyteArray barr) { char* rtn = NULL; jsize alen = (*env)->GetArrayLength(env, barr); jbyte* ba = (*env)->GetByteArrayElements(env, barr, 0); if (alen > 0) { rtn = (char*) malloc(alen + 1); memcpy(rtn, ba, alen); rtn[alen] = 0; } (*env)->ReleaseByteArrayElements(env, barr, ba, 0); return rtn;}//jni方法入口jstring Java_net_bither_util_NativeUtil_compressBitmap(JNIEnv* env, jobject thiz, jobject bitmapcolor, int w, int h, int quality, jbyteArray fileNameStr, jboolean optimize) { AndroidBitmapInfo infocolor; BYTE* pixelscolor; int ret; BYTE * data; BYTE *tmpdata; char * fileName = jstrinTostring(env, fileNameStr); //解码Android bitmap信息,并存储值infocolor中 if ((ret = AndroidBitmap_getInfo(env, bitmapcolor, &infocolor)) < 0) { LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret); return (*env)->NewStringUTF(env, "0");; } if ((ret = AndroidBitmap_lockPixels(env, bitmapcolor, &pixelscolor)) < 0) { LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret); } BYTE r, g, b; data = NULL; data = malloc(w * h * 3); tmpdata = data; int j = 0, i = 0; int color; //将bitmap转换为rgb数据 for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { color = *((int *) pixelscolor); r = ((color & 0x00FF0000) >> 16); g = ((color & 0x0000FF00) >> 8); b = color & 0x000000FF; *data = b; *(data + 1) = g; *(data + 2) = r; data = data + 3; pixelscolor += 4; } } AndroidBitmap_unlockPixels(env, bitmapcolor); //进行压缩 int resultCode= generateJPEG(tmpdata, w, h, quality, fileName, optimize); free(tmpdata); if(resultCode==0){ jstring result=(*env)->NewStringUTF(env, error); error=NULL; return result; } return (*env)->NewStringUTF(env, "1"); //success}
0 0
- 安卓NDK开发-实现图片的高效压缩
- 安卓NDK开发
- 安卓NDK开发
- 安卓图片压缩
- 安卓压缩图片
- 安卓图片压缩
- 安卓图片压缩
- 安卓图片压缩
- 安卓压缩图片
- 安卓eclipse 的ndk开发
- 安卓原生代码实现图片压缩框架
- EasyDarwin安卓直播之EasyPusher NDK开发:JNI回调函数的实现
- 一种高效压缩PNG图片的工具
- Android一种高效压缩图片的方法
- Android一种高效压缩图片的方法
- 安卓NDK开发中遇到的坑
- 安卓NDK开发案列一:字符串的加密和解密
- 安卓NDK开发案列三:文件的拆分与合并
- windows下安装numpy+mtk,scipy,python_speech_features
- 搭建git服务器——小组级别
- Unity3D - 导航网格自动寻路(Navigation Mesh)
- el表达式
- 二叉树的遍历与深度和节点数的计算代码实现
- 安卓NDK开发-实现图片的高效压缩
- 手机验证码
- break or continue java 8 stream lambda foreach(loop)
- [C++杂谈——effective C++略读]C++的构造、析构和赋值
- Transaction Isolation Level
- nyoj771密钥解密
- 1079. Total Sales of Supply Chain
- mac python链接数据库
- 551nod-【1138 连续整数的和】