从 JNI (OpenCV putText) 获取字符串以在 Java 中显示

Posted

技术标签:

【中文标题】从 JNI (OpenCV putText) 获取字符串以在 Java 中显示【英文标题】:Get String from JNI (OpenCV putText) to display in Java 【发布时间】:2016-01-03 15:04:21 【问题描述】:

我正在构建一个测量彩色圆圈之间距离的应用。我能够做到,但我想将测量数据(image)保存到我在 android 上创建的数据库(新活动中的表)中,但我不知道如何从 JNI 中获取绘制的字符串到我为数据库创建的活动。

//put text
putText(mBgra, format("blue-green distance: %.2f cm ",conv3), Point(50,200), FONT_HERSHEY_SIMPLEX, 1, Scalar(0 , 255 , 0 , 255), 4);

如何从上面的代码中获取字符串并将其显示到新的 java 活动中?

【问题讨论】:

你有代码吗?这是一个质量检查网站,你甚至没有问你的问题。您希望我们为您写这篇文章吗? @AustinWBryan 我已经编辑了我的帖子。 putText() 会产生一个位图,你可以在Android中显示这个位图。或者,您可以使用 JNI 更新活动中的某些文本字段。后一种方法通常更可取。 @AlexCohn 先生,你能提供一个关于如何做后者的例子吗?谢谢! 【参考方案1】:

假设有一个Java类

class MyClass 
    public String mSomething;

您将创建一个 MyClass 对象并将其作为 jobject myClassObject 传递给您的本机代码。

然后在你的C++代码中你可以写

jclass myClass = env->GetObjectClass(myClassObject);
if (myClass != NULL) 
    jfieldID fid = env->GetFieldID(MyClass, "mSomething", "Ljava/lang/String;");
    if (fid != NULL) 
        jstring jstr = env->NewStringUTF(format("blue-green distance: %.2f cm ",conv3).c_str());
        env->SetObjectField(myClassObject, fid, jstr);
    

出于性能考虑,fid 可能会被缓存并重复使用。如果您已经知道 fid,则无需获取 myClass

【讨论】:

我似乎无法让它工作。我在 jni 包上有这个浮点“conv3”:JNIEXPORT void JNICALL Java_com_example_alexies_objecttrackertest_UBackTrackViewer_UBackObjectTrack (JNIEnv * env , jobject ubackObject, jint width , jint height, jbyteArray yuv, jintArray bgra, jboolean debug),我想将该浮点的值传递给 java 活动。 请更具体 这是我的 jni 的完整代码:[pastebin] (pastebin.com/LBmucuch)。它在图像帧中找到并绘制蓝色和黄色的圆形图案,并测量它们之间的距离。我想将距离的值传递给我将用于数据库的 android 活动类。 距离应该去哪里?到 ubackObject 的浮点字段(由 i 0…circles->total-1 索引)?或者这个对象的字符串字段?或者你可以简单地从你的函数中返回一个浮点数(或字符串)数组。 我想将它的值传递到我活动的文本视图中。【参考方案2】:

这显示了如何pass the value into a textview on your activity。

我假设在

JNIEXPORT void JNICALL Java_com_example_alexies_objecttrackertest_UBackTrackViewer_UBackObjectTrack (JNIEnv * env , jobject ubackObject,
    jint width , jint height, jbyteArray yuv, jintArray bgra, jboolean debug)

UBackTrackViewer ubackObject 是您询问的活动,它定义了字段

private TextView mBlueGreenDistance, mBlueYellowDistance, mMagentaRedDistance;

在为活动加载布局后,您可能会初始化这些字段以指向 onCreate() 中的实际文本视图。

然后在您的 JNI 代码中,您将拥有这个初始化序列(在 textview 字段初始化后运行一次就足够了):

jclass UBackTrackViewer_CLS = env->FindClass("com/example/alexies/objecttrackertest/UBackTrackViewer");
jclass TextView_CLS = env->FindClass("android/widget/TextView");
jmethodID setText_MID = env->GetMethodID(TextView_CLS, "setText", "(Ljava/lang/CharSequence;)V");

jfieldID mBlueGreenDistance_FID = env->GetFieldID(UBackTrackViewer_CLS, "mBlueGreenDistance", "Landroid/widget/TextView;");
…

现在,借助这些全局变量,您可以将以下内容添加到您的本地方法中:

jobject mBlueGreenDistance_OBJ = env->GetObjectField(ubackObject, mBlueGreenDistance_FID);
jstring distance_STR = env->NewStringUTF(format("blue-green distance: %.2f cm", conv3).c_str());
env->CallVoidMethod(mBlueGreenDistance_OBJ, setText_MID, distance_STR);

在这种情况下不需要清理。不会发生内存或引用泄漏。请注意,setText() 方法必须从 UI 线程调用。

【讨论】:

以上是关于从 JNI (OpenCV putText) 获取字符串以在 Java 中显示的主要内容,如果未能解决你的问题,请参考以下文章

opencv文字旋转 putText旋转90°

OpenCV这么简单为啥不学——1.5解决putText中文乱码问题

利用OpenCV的函数putText()为图像添加数值型文本内容

OpenCV-文字绘制cv::putText

opencv 用puttext在视频上添加文字

JNI、NDK 和 OpenCV