【发布时间】:2018-09-08 04:46:33
【问题描述】:
我有 C/C++ 源代码(在 Windows 上运行良好)将输入帧转换为新帧。
现在我想将此 C/C++ 源代码移植到我的 Android 应用程序以转换设备 Camera2 的帧。
我将从 Java 应用程序中获取 Camera2 的连续字节 [] 帧,然后将其输入到 JNI 以接收转换后的字节 new_frame。
所以我在 JNI 中的流程必须是:
将 byte[] 帧从 Java 转换为 JNI jarrayByte
将 jarrayByte 转换为 jyte*
从 jbyte* 创建新的 cv::Mat 原件
将输入 cv::Mat 原始转换为使用 C/C++ 函数转换的新 cv::Mat
现在,我需要将 cv::Mat 转换为 jByteArray 以返回 Java 函数 => 我卡在这一步
所以我的问题是如何将 cv::mat 转换回 jbyteArray 以返回应用程序的 Java 层?
extern "C" JNIEXPORT jbyteArray
JNICALL
Java_com_xyz_NativeUtil_convertFrame(JNIEnv *env, jobject obj,
jbyteArray yuvFrame) {
// convert jByteArray to jbyte*
jbyte* yuvByte = env->GetByteArrayElements(yuvFrame, 0);
// convert jbyte* to cv::Mat
cv::Mat frame_original_yuv = cv::Mat(height + height/2, width, CV_8UC1, yuvByte);
// convert YUV cv::Mat to RGBA cv::Mat
cv::Mat frame_original_rgba = cv::Mat(height, width, CV_8UC4);
cv::cvtColor(frame_original_yuv, frame_original_rgba, CV_YUV2RGBA_NV21);
env->ReleaseByteArrayElements(yuvFrame, yuvByte, 0);
// convert frame
cv::Mat frame_converted = convert_frame(frame_original_rgba);
frame_original_yuv.release();
if (frame_converted .empty()) {
frame_converted = frame_original_rgba;
}
frame_original_rgba.release();
// convert cv::Mat to jbyteArray
jbyteArray result = ???
return result;
}
我的 Java 代码:
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = reader.acquireLatestImage();
if (image == null)
return;
Image.Plane Y = image.getPlanes()[0];
Image.Plane U = image.getPlanes()[1];
Image.Plane V = image.getPlanes()[2];
int Yb = Y.getBuffer().remaining();
int Ub = U.getBuffer().remaining();
int Vb = V.getBuffer().remaining();
byte[] yuvFrame = new byte[Yb + Ub + Vb];
Y.getBuffer().get(yuvFrame, 0, Yb);
U.getBuffer().get(yuvFrame, Yb, Ub);
V.getBuffer().get(yuvFrame, Yb + Ub, Vb);
image.close();
}
}, mBackgroundHandler);
【问题讨论】:
标签: android opencv java-native-interface