在Android NDK开发中将Bitmap集合返回给Java调用层输出的解决方案

需求:


NDK开发,输入一张Bitmap图片,然后使用OpenCV等工具去处理,如调节亮度、白平衡、图像负片效,黑白效果等,再将它们添加到一个数组集合中,一起返回给Java调用函数输出。如下图所示:

在Android NDK开发中将Bitmap集合返回给Java调用层输出的解决方案_第1张图片

 那么我们要如何去实现这个功能呢?

因为要使用到C/C++,所有对外接口需要封装成JNI接口,传入Bitmap图像使用OpenCV库等工具进行处理后,再返回给Java调用层作输出显示,如果图像数据的传递采用裸数据的形式,直接将传回图像像素值数组明显是很难实现的,这时就需要通过在JNI中利用反射技术,将Java的List、Bitmap等类反射到JNI中去实现了,具体操作如下:

核心代码:

    /**
     * 返回图像列表
     * @param env
     * @param clazz
     * @param bitmap
     * @return
     */
    JNIEXPORT jobject JNICALL
    Java_com_example_bitmaplists_Process_getBitmapLists(JNIEnv *env, jclass clazz, jobject bitmap) {
        //获取ArrayList类引用
        jclass list_cls = env->FindClass("java/util/ArrayList");
        if (list_cls == nullptr) {
            return nullptr;
        }
        //获取ArrayList构造函数ID
        jmethodID list_init = env->GetMethodID(list_cls, "", "()V");
        //创建一个ArrayList对象
        jobject list_obj = env->NewObject(list_cls, list_init, "");
        //获取ArrayList对象的add()方法
        jmethodID list_add = env->GetMethodID(list_cls, "add", "(Ljava/lang/Object;)Z");
        //获取Func实体类
        jclass jcls = env->FindClass("com/example/bitmaplists/Func");
        //获取Func实体类属性
        jfieldID bit = env->GetFieldID(jcls, "bitmap", "Landroid/graphics/Bitmap;");
        jfieldID name = env->GetFieldID(jcls, "funcName", "Ljava/lang/String;");
 
        std::string str[] = {"负像效果", "连环画", "白平衡", "亮度调节"};
 
        cv::Mat image;
        BitmapToMatrix(env, bitmap, image);
        std::vector data;
 
        Mat a1 = Invert(image);
        data.push_back(a1);
 
        Mat a2 = ComicStrips(image);
        data.push_back(a2);
 
        Mat a3;
        AutoWhiteBalance(image, a3);
        data.push_back(a3);
 
        Mat a4;
        Brightness(image, a4, 1.2, 0);
        data.push_back(a4);
 
        for (int i = 0; i < data.size(); i++) {
            jobject jobj = env->AllocObject(jcls);
            cv::Mat img = data[i];
            jobject out = BitmapConfigure(env, img);
            MatrixToBitmap(env, img, out);
            //根据Func实体类属性设置字段值
            env->SetObjectField(jobj, bit, out);
            env->SetObjectField(jobj, name, env->NewStringUTF(str[i].c_str()));
            //调用ArrayList中的add()方法
            env->CallBooleanMethod(list_obj, list_add, jobj);
            //销毁目示对象
            env->DeleteLocalRef(jobj);
        }
        return list_obj;
    }

源码下载:AndroidNDK中将图像列表返回给Java调用层处理方法

你可能感兴趣的:(图像处理,Android,android,opencv,图像处理,c++,计算机视觉)