【发布时间】:2017-12-16 12:28:48
【问题描述】:
我想在 android 模拟器上显示一个 Mat 图像。我将assetManager 从java 传递到c++ 并将图像作为资产加载。然后我执行 AAsset_read,并将图像数据保存到 char* 缓冲区,并使用 cv::imdecode 转换为 Mat。
从这里开始,我该如何将 Mat 图像添加到模拟器中?
在默认的stringFromJNI 方法中,他们似乎使用了显示文本的return->envNewStringUTF(hello.c_str());:
Java_com_example_user_project_MainActivity_stringFromJNI(JNIEnv *env, jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
那么我该如何处理 Mat 图像呢?
编辑:这是我的 C++ 代码:
JNIEXPORT jintArray JNICALL Java_com_example_user_activity_MainActivity_generateAssets(JNIEnv* env,jobject thiz,jobject assetManager) {
AAsset* img;
AAssetManager *mgr = AAssetManager_fromJava(env, assetManager);
AAssetDir* assetDir = AAssetManager_openDir(mgr, "");
const char* filename;
while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) {
AAsset *asset = AAssetManager_open(mgr, filename, AASSET_MODE_UNKNOWN);
if(strcmp(filename, "hi.jpg")==0 ) {
img = asset;
}
}
long sizeOfImg = AAsset_getLength(img);
char* buffer = (char*) malloc (sizeof(char)*sizeOfImg);
AAsset_read(img, buffer, sizeOfImg);
std::vector<char> data(buffer, buffer + sizeOfImg);
cv::Mat h = cv::imdecode(data, IMREAD_UNCHANGED);
jintArray resultImage = env->NewIntArray(h.total());
jint *_data = new jint[h.total()];
for (int i = 0; i < h.total(); i++) {
char b = h.data[4 * i];
char g = h.data[4 * i + 1];
char r = h.data[4 * i + 2];
char a = 255;
_data[i] = (((jint) a << 24) & 0xFF000000) + (((jint) r << 16) & 0x00FF0000) +
(((jint) g << 8) & 0x0000FF00) + ((jint) b & 0x000000FF);
}
env->SetIntArrayRegion(resultImage, 0, h.total(), _data);
delete[]_data;
return resultImage;
}
还有java代码:
assetManager = getAssets();
resultImage = generateAssets(assetManager);
Bitmap imageinjava = Bitmap.createBitmap(resultImage, 100,100, Bitmap.Config.ARGB_8888);
ImageView tv1;
tv1= (ImageView) findViewById(R.id.image);
tv1.setImageBitmap(imageinjava);
【问题讨论】:
-
“将 Mat 图像添加到模拟器”是什么意思?
-
只显示在屏幕上。就像代码如何显示“来自 c++ 的你好”一样,我想显示图像
-
如果您不使用 java opencv API - 最好的目标是从您的图像创建位图。您可以使用 Mat 对象的 RGBA 数据返回 jintArray,然后通过调用 Bitmap.createBitmap 创建位图
-
对不起,我应该提到这一点 - 我正在使用 OpenCV 并且需要它作为 Mat 对象,因为我想稍后对 Mat 对象进行进一步处理。这只是一个helloworld阶段。
-
如果你想在 java 和 c++ 之间传递原生对象,那么你可以返回指向 Mat 对象的指针。虽然(不使用 opencv java api)
标签: java android c++ opencv java-native-interface