1.JNI实现Bitmap到Mat的转换
void bitmap2mat(JNIEnv *env, jobject bitmap,Mat &mat){ //锁定画布 void *pixels; AndroidBitmap_lockPixels(env,bitmap,&pixels); //获取Bitmap的信息 AndroidBitmapInfo bitmapInfo; AndroidBitmap_getInfo(env,bitmap,&bitmapInfo); //判断图像通道数 if(bitmapInfo.format==AndroidBitmapFormat::ANDROID_BITMAP_FORMAT_RGBA_8888){//mat的四通道 LOGD("图像4通道"); Mat image(bitmapInfo.height,bitmapInfo.width,CV_8UC4,pixels); image.copyTo(mat);//深拷贝 }else if(bitmapInfo.format==AndroidBitmapFormat::ANDROID_BITMAP_FORMAT_RGB_565){//mat的二通道CV_8UC2 LOGD("图像2通道"); Mat image(bitmapInfo.height,bitmapInfo.width,CV_8UC2,pixels); image.copyTo(mat); }else{ } //解锁画布 AndroidBitmap_unlockPixels(env,bitmap); }
调用示例:
extern "C" JNIEXPORT void JNICALL Java_com_example_myapplication_MainActivity_opencv_1test(JNIEnv *env, jclass clazz, jobject bitmap) { Mat mat; bitmap2mat(env, bitmap, mat); imwrite("/sdcard/DCIM/bitmap2img.png",mat); }
2.JNI实现Mat到Bitmap的转换
void mat2bitmap(JNIEnv *env, jobject bitmap,Mat &mat){ //锁定画布 void *pixels; AndroidBitmap_lockPixels(env,bitmap,&pixels); //获取Bitmap的信息 AndroidBitmapInfo bitmapInfo; AndroidBitmap_getInfo(env,bitmap,&bitmapInfo); int ret; // 将Mat数据复制到Bitmap cv::Mat bitmapMat(bitmapInfo.height, bitmapInfo.width, CV_8UC4, pixels); mat.copyTo(bitmapMat);//深拷贝 AndroidBitmap_unlockPixels(env, bitmap);//解锁画布 }
调用示例:
extern "C" JNIEXPORT void JNICALL Java_com_example_myapplication_MainActivity_opencv_1test(JNIEnv *env, jclass clazz, jobject bitmap) { //获取Bitmap的信息 AndroidBitmapInfo bitmapInfo; AndroidBitmap_getInfo(env,bitmap,&bitmapInfo); //创建和Bitmap尺寸相同的Mat对象 Mat mat1(bitmapInfo.height ,bitmapInfo.width,CV_8UC4,Scalar(0,0,255,255)); //把mat对象的像素数据复制到bitmap中 mat2bitmap(env,bitmap,mat1); }
完整代码:
#include <opencv2/core.hpp> #include <opencv2/imgproc.hpp> #include <jni.h> #include <android/bitmap.h> #include <opencv2/opencv.hpp> #include <android/log.h> #define LOG_TAG "xxx" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) using namespace cv; using namespace std; void bitmap2mat(JNIEnv *env, jobject bitmap,Mat &mat); void mat2bitmap(JNIEnv *env, jobject bitmap,Mat &mat); void bitmap2mat(JNIEnv *env, jobject bitmap,Mat &mat){ //锁定画布 void *pixels; AndroidBitmap_lockPixels(env,bitmap,&pixels); //获取Bitmap的信息 AndroidBitmapInfo bitmapInfo; AndroidBitmap_getInfo(env,bitmap,&bitmapInfo); //判断图像通道数 if(bitmapInfo.format==AndroidBitmapFormat::ANDROID_BITMAP_FORMAT_RGBA_8888){//mat的四通道 LOGD("图像4通道"); Mat image(bitmapInfo.height,bitmapInfo.width,CV_8UC4,pixels); image.copyTo(mat);//深拷贝 }else if(bitmapInfo.format==AndroidBitmapFormat::ANDROID_BITMAP_FORMAT_RGB_565){//mat的二通道CV_8UC2 LOGD("图像2通道"); Mat image(bitmapInfo.height,bitmapInfo.width,CV_8UC2,pixels); image.copyTo(mat); }else{ LOGD("图像3通道"); Mat image(bitmapInfo.height,bitmapInfo.width,CV_8UC3,pixels); image.copyTo(mat); } //解锁画布 AndroidBitmap_unlockPixels(env,bitmap); } void mat2bitmap(JNIEnv *env, jobject bitmap,Mat &mat){ //锁定画布 void *pixels; AndroidBitmap_lockPixels(env,bitmap,&pixels); //获取Bitmap的信息 AndroidBitmapInfo bitmapInfo; AndroidBitmap_getInfo(env,bitmap,&bitmapInfo); int ret; // 将Mat数据复制到Bitmap cv::Mat bitmapMat(bitmapInfo.height, bitmapInfo.width, CV_8UC4, pixels); mat.copyTo(bitmapMat); AndroidBitmap_unlockPixels(env, bitmap); }
在 Android 通过 JNI 去调用 Bitmap,通过 CMake 去编 so 动态链接库的话,需要添加 jnigraphics 图像库。
target_link_libraries(
#在target_link_libraries中添加下面的依赖项
jnigraphics
)