[Android jni] Bitmap与Mat对象的相互转换

简介: [Android jni] Bitmap与Mat对象的相互转换

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

       )

 

目录
相关文章
|
Android开发
Android JNI与CAN通信遇到的问题总结
Android JNI与CAN通信遇到的问题总结
671 1
|
2月前
|
存储 消息中间件 人工智能
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
105 11
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
|
Java Android开发 C++
Android Studio JNI 使用模板:c/cpp源文件的集成编译,快速上手
本文提供了一个Android Studio中JNI使用的模板,包括创建C/C++源文件、编辑CMakeLists.txt、编写JNI接口代码、配置build.gradle以及编译生成.so库的详细步骤,以帮助开发者快速上手Android平台的JNI开发和编译过程。
1010 1
|
存储 缓存 编解码
Android经典面试题之图片Bitmap怎么做优化
本文介绍了图片相关的内存优化方法,包括分辨率适配、图片压缩与缓存。文中详细讲解了如何根据不同分辨率放置图片资源,避免图片拉伸变形;并通过示例代码展示了使用`BitmapFactory.Options`进行图片压缩的具体步骤。此外,还介绍了Glide等第三方库如何利用LRU算法实现高效图片缓存。
200 20
Android经典面试题之图片Bitmap怎么做优化
|
存储 Java Android开发
Android上在两个Activity之间传递Bitmap对象
Android上在两个Activity之间传递Bitmap对象
128 2
|
XML API 开发工具
Android Bitmap 加载与像素操作
Android Bitmap 加载与像素操作
146 2
|
XML 前端开发 API
Android中实现Bitmap在自定义View中的放大与拖动
Android中实现Bitmap在自定义View中的放大与拖动
256 1
|
Java Android开发
Android JNI 调用
Android JNI 调用
174 1
|
XML Android开发 数据格式
Android五大布局对象---FrameLayout,LinearLayout ,Absolute
Android五大布局对象---FrameLayout,LinearLayout ,Absolute
146 1
|
Java Android开发
程序与技术分享:Android使用Dagger注入的方式初始化对象的简单使用
程序与技术分享:Android使用Dagger注入的方式初始化对象的简单使用
315 0