初次使用cmake来编译c文件在Android项目中,那个快感能传递到骨髓里,欲罢不能.只能说谁用谁知道.如果还没有使用,请赶快用一次,初次体验一共三部:
第一:studio升级到2.2以后的版本,安装NDK,cmake工具
第二:创建新项目勾选 Include C++ Support 选项。
第三:一路下一步,安装运行项目
studio会默认帮你创建一个写好的demo更加详细的请参考:http://blog.csdn.net/wl9739/article/details/52607010或者google官网:https://developer.android.com/ndk/guides/build.html
我今天以自己学到的使用c代码压缩图片为例子,用cmake来编译这个项目来分享下学到的东西,如果使用cmake来编译项目一共有两种实现方式:
第一种就是上面那样,创建项目时勾选Include C++ Support 让系统生成配置,然后自己再添加c代码,
第二种是不是新建的项目,这时候要引用c代码,那就要自己去配置文件,本文就要讲后面这种实现方式.
先看看效果图:
这两张是从相册倒出来的,压缩前压缩后的
右图原图1.67M 左图压缩后57.54K不到原来的1/10,不放大的情况,用肉眼很难分辨出来差别.
要把这个c代码图片压缩集成到项目中需要四部:
第一:准备2.2以上版本studio,配置安装ndk和cmake工具
第二:导入c++文件,修改方法名
在项目module目录下新建cpp文件夹,一定要注意不要建错地方了,最终绝对路径是app\src\main\cpp,把native-lib.cpp这个文件导入到你自己的cpp文件夹中
native-lib.cpp文件如下
#include
#include
#include
#include
#include
#include
#include
#include
extern "C" {
#include "jpeglib.h"
#include "jversion.h"
#include "cdjpeg.h"
#include "android/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 0
typedef 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 = (char *) 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) {
//jpeg的结构体,保存的比如宽、高、位深、图片格式等信息,相当于java的类
struct jpeg_compress_struct jcs;
//当读完整个文件的时候就会回调my_error_exit这个退出方法。setjmp是一个系统级函数,是一个回调。
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;
}
//初始化jsc结构体
jpeg_create_compress(&jcs);
//打开输出文件 wb:可写byte
FILE *f = fopen(outfilename, "wb");
if (f == NULL) {
return 0;
}
//