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


    1.JNI实现Bitmap到Mat的转换

    1. void bitmap2mat(JNIEnv *env, jobject bitmap,Mat &mat){
    2. //锁定画布
    3. void *pixels;
    4. AndroidBitmap_lockPixels(env,bitmap,&pixels);
    5. //获取Bitmap的信息
    6. AndroidBitmapInfo bitmapInfo;
    7. AndroidBitmap_getInfo(env,bitmap,&bitmapInfo);
    8. //判断图像通道数
    9. if(bitmapInfo.format==AndroidBitmapFormat::ANDROID_BITMAP_FORMAT_RGBA_8888){//mat的四通道
    10. LOGD("图像4通道");
    11. Mat image(bitmapInfo.height,bitmapInfo.width,CV_8UC4,pixels);
    12. image.copyTo(mat);//深拷贝
    13. }else if(bitmapInfo.format==AndroidBitmapFormat::ANDROID_BITMAP_FORMAT_RGB_565){//mat的二通道CV_8UC2
    14. LOGD("图像2通道");
    15. Mat image(bitmapInfo.height,bitmapInfo.width,CV_8UC2,pixels);
    16. image.copyTo(mat);
    17. }else{
    18. }
    19. //解锁画布
    20. AndroidBitmap_unlockPixels(env,bitmap);
    21. }

    调用示例:

    1. extern "C"
    2. JNIEXPORT void JNICALL
    3. Java_com_example_myapplication_MainActivity_opencv_1test(JNIEnv *env, jclass clazz,
    4. jobject bitmap) {
    5. Mat mat;
    6. bitmap2mat(env, bitmap, mat);
    7. imwrite("/sdcard/DCIM/bitmap2img.png",mat);
    8. }

    2.JNI实现Mat到Bitmap的转换

    1. void mat2bitmap(JNIEnv *env, jobject bitmap,Mat &mat){
    2. //锁定画布
    3. void *pixels;
    4. AndroidBitmap_lockPixels(env,bitmap,&pixels);
    5. //获取Bitmap的信息
    6. AndroidBitmapInfo bitmapInfo;
    7. AndroidBitmap_getInfo(env,bitmap,&bitmapInfo);
    8. int ret;
    9. // 将Mat数据复制到Bitmap
    10. cv::Mat bitmapMat(bitmapInfo.height, bitmapInfo.width, CV_8UC4, pixels);
    11. mat.copyTo(bitmapMat);//深拷贝
    12. AndroidBitmap_unlockPixels(env, bitmap);//解锁画布
    13. }

     调用示例:

    1. extern "C"
    2. JNIEXPORT void JNICALL
    3. Java_com_example_myapplication_MainActivity_opencv_1test(JNIEnv *env, jclass clazz,
    4. jobject bitmap) {
    5. //获取Bitmap的信息
    6. AndroidBitmapInfo bitmapInfo;
    7. AndroidBitmap_getInfo(env,bitmap,&bitmapInfo);
    8. //创建和Bitmap尺寸相同的Mat对象
    9. Mat mat1(bitmapInfo.height ,bitmapInfo.width,CV_8UC4,Scalar(0,0,255,255));
    10. //把mat对象的像素数据复制到bitmap中
    11. mat2bitmap(env,bitmap,mat1);
    12. }

    完整代码:

    1. #include <opencv2/core.hpp>
    2. #include <opencv2/imgproc.hpp>
    3. #include <jni.h>
    4. #include <android/bitmap.h>
    5. #include <opencv2/opencv.hpp>
    6. #include <android/log.h>
    7. #define LOG_TAG "xxx"
    8. #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
    9. using namespace cv;
    10. using namespace std;
    11. void bitmap2mat(JNIEnv *env, jobject bitmap,Mat &mat);
    12. void mat2bitmap(JNIEnv *env, jobject bitmap,Mat &mat);
    13. void bitmap2mat(JNIEnv *env, jobject bitmap,Mat &mat){
    14. //锁定画布
    15. void *pixels;
    16. AndroidBitmap_lockPixels(env,bitmap,&pixels);
    17. //获取Bitmap的信息
    18. AndroidBitmapInfo bitmapInfo;
    19. AndroidBitmap_getInfo(env,bitmap,&bitmapInfo);
    20. //判断图像通道数
    21. if(bitmapInfo.format==AndroidBitmapFormat::ANDROID_BITMAP_FORMAT_RGBA_8888){//mat的四通道
    22. LOGD("图像4通道");
    23. Mat image(bitmapInfo.height,bitmapInfo.width,CV_8UC4,pixels);
    24. image.copyTo(mat);//深拷贝
    25. }else if(bitmapInfo.format==AndroidBitmapFormat::ANDROID_BITMAP_FORMAT_RGB_565){//mat的二通道CV_8UC2
    26. LOGD("图像2通道");
    27. Mat image(bitmapInfo.height,bitmapInfo.width,CV_8UC2,pixels);
    28. image.copyTo(mat);
    29. }else{
    30. LOGD("图像3通道");
    31. Mat image(bitmapInfo.height,bitmapInfo.width,CV_8UC3,pixels);
    32. image.copyTo(mat);
    33. }
    34. //解锁画布
    35. AndroidBitmap_unlockPixels(env,bitmap);
    36. }
    37. void mat2bitmap(JNIEnv *env, jobject bitmap,Mat &mat){
    38. //锁定画布
    39. void *pixels;
    40. AndroidBitmap_lockPixels(env,bitmap,&pixels);
    41. //获取Bitmap的信息
    42. AndroidBitmapInfo bitmapInfo;
    43. AndroidBitmap_getInfo(env,bitmap,&bitmapInfo);
    44. int ret;
    45. // 将Mat数据复制到Bitmap
    46. cv::Mat bitmapMat(bitmapInfo.height, bitmapInfo.width, CV_8UC4, pixels);
    47. mat.copyTo(bitmapMat);
    48. AndroidBitmap_unlockPixels(env, bitmap);
    49. }

    Android 通过 JNI 去调用 Bitmap,通过 CMake 去编 so 动态链接库的话,需要添加 jnigraphics 图像库。

    target_link_libraries( 
            #在target_link_libraries中添加下面的依赖项
            jnigraphics
            )


     

  • 相关阅读:
    git stash使用场景
    Python 项目一 数据可视化 01
    组件库自定义主题换肤实现方案
    贝叶斯分类(朴素)
    Linux安装mysql
    2014年3月13日 Go生态洞察:并发模式与管道取消技术
    人工智能安全-5-网络入侵检测
    蓝桥等考Python组别二级004
    线程调度算法?
    维修一款20年前的电容测试表VC6013
  • 原文地址:https://blog.csdn.net/weixin_63357306/article/details/132851451