【问题标题】:send images from android studio to cpp将图像从 android studio 发送到 cpp
【发布时间】:2020-04-29 22:50:06
【问题描述】:

我们在 android studio 中开发一个项目。 我们尝试将图像数组从 java 部分发送到 cpp。 然后,我们想做一些图像处理动作,然后将图像发送回java端。

我们将每个图像表示为一个矩阵,并尝试创建要发送的矩阵数组。 我们尝试了几种不同的方法,但找不到正确的方法


Java:

static Mat[] imageMats = new Mat[3];

@Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.imageToUpload:
                Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(galleryIntent, RESUALT_LOAD_IMAGE);
                break;
            case R.id.bottonUpload:

                start(imageMats, counter)

public native Mat start(Mat[] imageMats, int N);


Cpp:
Mat
Java_com_example_trycpp_MainActivity_start(JNIEnv* env, jobject thisobject, jobjectArray imageMats, jint N){
Data D;
D.source = vector<cv::Mat>(N)
for (int i = 0; i < N; ++i)
{
    D.sources[i] = (cv::Mat)(imageMats[i]); //error - _jobjectArray can't be cast to type "Mat": class "_jobjectAray" is not compatible with class "Mat"
}

}

我们也尝试在 cpp 部分使用这种方式,但应用程序崩溃了。当我们尝试调试时,我们看到了分段错误:

cpp:
jclass thisclass = env->GetObjectClass(thisobject);
jclass matclass = (env)->FindClass("org/opencv/core/Mat");

// Get methods and fields
jmethodID getPtrMethod = (env)->GetMethodID(matclass, "getNativeObjAddr", "()J");
jfieldID mrgbafieldid = env->GetFieldID(thisclass, "mRgba", "Lorg/opencv/core/Mat;");
jfieldID bufimgsfieldid = env->GetFieldID(thisclass, "bufImgs", "[Lorg/opencv/core/Mat;");

// Let's start: Get the fields
jobject mrgba = env->GetObjectField(thisobject, mrgbafieldid);
jobjectArray bufimgsArray = (jobjectArray)env->GetObjectField(thisobject, bufimgsfieldid);
D.sources[i] = *(cv::Mat*)env->CallLongMethod(env->GetObjectArrayElement(imageMats, i), getPtrMethod);

【问题讨论】:

    标签: java android c++ android-studio opencv


    【解决方案1】:

    要将图像从 Android 部件传递到原生部件,您可以使用 NDK 中的 android/bitmap.h

    这是一个将位图转换为 Array2D(来自 dlib)的示例。我希望您可以根据自己的情况进行调整。

    #include "jni.h"
    #include "android/log.h"
    #include "android/bitmap.h"
    
    #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,    TAG, __VA_ARGS__)
    #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,     TAG, __VA_ARGS__)
    
    void convertBitmapToArray2d(JNIEnv *env,
                                jobject bitmap,
                                dlib::array2d<dlib::bgr_pixel> &out) {
        AndroidBitmapInfo bitmapInfo;
        void *pixels;
        int state;
    
        if (0 > (state = AndroidBitmap_getInfo(env, bitmap, &bitmapInfo))) {
            LOGE("AndroidBitmap_getInfo() failed! error=%d", state);
            return;
        } else if (bitmapInfo.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
            LOGE("Bitmap format is not RGB_565!");
        }
    
        // Lock the bitmap for copying the pixels safely.
        if (0 > (state = AndroidBitmap_lockPixels(env, bitmap, &pixels))) {
            LOGE("AndroidBitmap_lockPixels() failed! error=%d", state);
            return;
        }
    
        LOGI("info.width=%d, info.height=%d", bitmapInfo.width, bitmapInfo.height);
        out.set_size((long) bitmapInfo.height, (long) bitmapInfo.width);
    
        char *line = (char *) pixels;
        for (int h = 0; h < bitmapInfo.height; ++h) {
            for (int w = 0; w < bitmapInfo.width; ++w) {
                uint32_t *color = (uint32_t *) (line + 4 * w);
    
                out[h][w].red = (unsigned char) (0xFF & (*color));
                out[h][w].green = (unsigned char) (0xFF & ((*color) >> 8));
                out[h][w].blue = (unsigned char) (0xFF & ((*color) >> 16));
            }
    
            line = line + bitmapInfo.stride;
        }
    
        // Unlock the bitmap.
        AndroidBitmap_unlockPixels(env, bitmap);
    }
    

    【讨论】:

    • 感谢您的帮助,我们不明白如何在我们的项目中使用您的想法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-26
    • 2014-06-29
    • 1970-01-01
    • 2019-05-04
    • 2016-08-02
    • 2015-10-23
    • 2014-03-10
    相关资源
    最近更新 更多