帮助集成第三方jni代码。c、c++需要额外学习才能精通ndk开发。
第一个是文件加密解密,分割合并。
extern "C"
JNIEXPORT jboolean JNICALL
Java_cn_cfanr_ndksample_utils_FileUtils_fileEncrypt(JNIEnv *env, jclass type, jstring normalFilePath_,
jstring encryptFilePath_) {
const char *normalFilePath = env->GetStringUTFChars(normalFilePath_, 0);
const char *encryptFilePath = env->GetStringUTFChars(encryptFilePath_, 0);
int passwordLen = strlen(PASSWORD);
LOGE("要加密的文件的路径 = %s , 加密后的文件的路径 = %s", normalFilePath, encryptFilePath);
//读文件指针
FILE *frp = fopen(normalFilePath, "rb");
// 写文件指针
FILE *fwp = fopen(encryptFilePath, "wb");
if (frp == NULL) {
LOGE("文件不存在");
return JNI_FALSE;
}
if (fwp == NULL) {
LOGE("没有写权限");
return JNI_FALSE;
}
// 边读边写边加密
int buffer;
int index = 0;
while ((buffer = fgetc(frp)) != EOF) {
// write
fputc(buffer ^ *(PASSWORD + (index % passwordLen)), fwp); //异或的方式加密
index++;
}
// 关闭文件流
fclose(fwp);
fclose(frp);
LOGE("文件加密成功");
env->ReleaseStringUTFChars(normalFilePath_, normalFilePath);
env->ReleaseStringUTFChars(encryptFilePath_, encryptFilePath);
return JNI_TRUE;
}
直接通过c中的fputc函数,进行异或运算。
需要注意当我把图片压缩c代码放在与当前目录时,编译报错。因此新建module,独立CMakeLists工程编译两个项目。
第二个,图片质量压缩。
CMakeLists.txt
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
#设置生成的so动态库最后输出的路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI})
#指定要引用的libjpeg.so的头文件目录
set(LIBJPEG_INCLUDE_DIR src/main/cpp/include)
include_directories(${LIBJPEG_INCLUDE_DIR})
#导入libjpeg动态库 SHARED;静态库为STATIC
add_library(jpeg SHARED IMPORTED)
#对应so目录,这里为了简单设置的是绝对路径(注意要先 add_library,再 set_target_properties)
set_target_properties(jpeg PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}/libjpeg.so)
add_library(
compress
SHARED
src/main/cpp/compress.c
)
find_library(graphics jnigraphics)
find_library(log-lib log)
target_link_libraries(compress jpeg ${log-lib} ${graphics})
引入了graphics库,和libjpeg.so动态库。
JNIEXPORT jboolean JNICALL
Java_cn_cfanr_compress_ImageCompress_compressBitmap(JNIEnv *env, jclass type, jobject bitmap,
jstring dstPath_, jint quality,
jboolean isOptimize) {
AndroidBitmapInfo androidBitmapInfo;
BYTE *pixelsColor;
int ret;
BYTE *data;
BYTE *tmpData;
const char *dstFileName = jstringToString(env, dstPath_);
//解码Android Bitmap信息
if ((ret = AndroidBitmap_getInfo(env, bitmap, &androidBitmapInfo)) < 0) {
LOGD("AndroidBitmap_getInfo() failed error=%d", ret);
return false;
}
if ((ret = AndroidBitmap_lockPixels(env, bitmap, (void **)&pixelsColor)) < 0) {
LOGD("AndroidBitmap_lockPixels() failed error=%d", ret);
return false;
}
LOGD("bitmap: width=%d,height=%d,size=%d , format=%d ",
androidBitmapInfo.width, androidBitmapInfo.height,
androidBitmapInfo.height * androidBitmapInfo.width,
androidBitmapInfo.format);
BYTE r, g, b;
int color;
int w, h, format;
w = androidBitmapInfo.width;
h = androidBitmapInfo.height;
format = androidBitmapInfo.format;
data = (BYTE *) malloc(androidBitmapInfo.width * androidBitmapInfo.height * 3);
tmpData = data;
// 将bitmap转换为rgb数据
for (int i = 0; i < h; ++i) {
for (int j = 0; j < w; ++j) {
//只处理 RGBA_8888
if (format == ANDROID_BITMAP_FORMAT_RGBA_8888) {
color = (*(int *) (pixelsColor));
// 这里取到的颜色对应的 A B G R 各占8位
b = (color >> 16) & 0xFF;
g = (color >> 8) & 0xFF;
r = (color >> 0) & 0xFF;
*data = r;
*(data + 1) = g;
*(data + 2) = b;
data += 3;
pixelsColor += 4;
} else {
return -2;
}
}
}
AndroidBitmap_unlockPixels(env, bitmap);
//进行压缩
ret = generateJPEG(tmpData, w, h, quality, dstFileName, isOptimize);
free((void *) dstFileName);
free((void *) tmpData);
return true;
}
完整项目代码:https://github.com/androiddeveloper007/NdkProjectCollect
网友评论