imread在普通的c++程序中可以工作,但在android的ndk原生程序中就不行了。

问题描述 投票:0回答:1
#include <jni.h>
#include <string>

#include <opencv2/opencv.hpp>
using namespace cv;

#include <iostream>

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_cppinandroid_MainActivity_stringFromJNI( JNIEnv* env,
                            jobject)
{
    Mat image;
    image = imread( "/home/<name>/a.png", 1 );

    if ( !image.data )
    {
        return env->NewStringUTF( "No data in image!" );
    } else
    {
        return env->NewStringUTF( "Data is in image" );
    }
}

这就是我在android项目的Native Cpp部分。当我用模拟器运行应用程序时,它总是显示。"No data in image!" text.

我已经把这个程序单独编译成一个普通的c++ opencv程序。它工作得非常好。我也给了绝对路径。这还不够吗?

我必须在 build.gradle 还?

我使用的是Android studio,如果这有关系的话。

android c++ android-studio android-ndk ubuntu-16.04
1个回答
1
投票

Android目录与Linux完全不匹配。

一个好的解决方案是通过Java找到你的文件,并将文件的路径作为参数传递给函数Java_com_example_cppinandroid_MainActivity_stringFromJNI。

如果你的文件在公共文件中,你可以尝试 "sdcarda.png"--但不同的android shell的路径可能会有所不同。

从公共文件中读取的可能的解决方案。

Java:

File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+ File.separator + fileName);
if (f.exists()) {
foo(f.getAbsolutePath());

NDK:

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_cppinandroid_MainActivity_stringFromJNI(JNIEnv* env,
                            jobject, jstring javaPath)
{
    const char* path = env->GetStringUTFChars(javaPath, 0);
    Mat image;
    image = imread( path, 1 );
    env->ReleaseStringUTFChars(javaPath, path );
    if ( !image.data )
    {
        return env->NewStringUTF( "No data in image!" );
    } else
    {
        return env->NewStringUTF( "Data is in image" );
    }
}

一个更好的方法是将图片存储在assets中,并像AAssetManager那样读取。Android使用C(ndk)从asset文件夹中读取文本文件。如何在Android中使用JNI将资产FileDescriptor正确传递给FFmpeg?.

© www.soinside.com 2019 - 2024. All rights reserved.