【问题标题】:imread works in a normal c++ program, but not in android with ndk nativeimread 适用于普通的 c++ 程序,但不适用于带有 ndk native 的 android
【发布时间】:2020-05-09 13:41:51
【问题描述】:
#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】:

    Android 目录根本不匹配 Linux。

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

    如果您的文件在公共文件中,您可以尝试“/sdcard/a.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" );
        }
    }
    

    一种将图片存储在资产中并读取 AAssetManager 的更好方法,例如 Android read text file from asset folder using C (ndk)How to properly pass an asset FileDescriptor to FFmpeg using JNI in Android

    【讨论】:

    • 谢谢。所以,你的意思是说我们不能通过在 Android 的 C++ 中给出绝对地址来直接获取文件。没有办法吗?
    • 可以通过Environment.getExternalStorageDirectory().getAbsolutePath()获取公共文件的绝对路径。这种方法更容易调试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 1970-01-01
    相关资源
    最近更新 更多