贵有恒,何必三更起、五更眠、最无益,只怕一日曝、十日寒。这篇文章主要讲述如何在Android模拟器上显示Mat图像?使用NDK相关的知识,希望能为你提供帮助。
我想在android模拟器上显示Mat图像。我将一个assetManager从java
传递给c++
并将图像作为资产加载。然后我执行AAsset_read,并将图像数据保存到char *缓冲区,并使用cv::imdecode
转换为Mat。从这里开始,如何将Mat图像添加到模拟器?
【如何在Android模拟器上显示Mat图像(使用NDK)】在默认的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 JNICALLJava_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 = https://www.songbingjia.com/android/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图像,您可以这样做:
JNIEXPORT jintArray JNICALLJava_com_example_user_activity_MainActivity_generateAssets(JNIEnv* env, jobject thiz, jobject assetManager) {
AAssetManager *mgr = AAssetManager_fromJava(env, assetManager);
AAsset *img = AAssetManager_open(mgr, "hi.jpg", AASSET_MODE_UNKNOWN);
long sizeOfImg = AAsset_getLength(img);
char* buffer = (char*)AAsset_getBuffer(img);
std::vector<
char>
data(buffer, buffer + sizeOfImg);
cv::Mat h = cv::imdecode(data, IMREAD_UNCHANGED);
jintArray resultImage = env->
NewIntArray(h.total());
jint *_data = https://www.songbingjia.com/android/new jint[h.total()];
for (int i = 0;
i <
h.total();
i++) {
char b = h.data[h.channels() * i];
char g = h.data[h.channels() * i + 1];
char r = h.data[h.channels() * 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代码中就像这样
int[] result = generateAssets(getAssets());
Bitmap bitmap = Bitmap.createBitmap(result, yourimagewidth, yourimageheight, Bitmap.Config.ARGB_8888);
如果要在c ++和java之间传递本机Mat对象 - 返回指向Mat的指针并稍后将其传递给本机函数;
Mat *mat = new Mat(100, 100);
return (jlong) mat;
推荐阅读
- Android JNI(将cv :: Mat转换为jbyteArray)
- 当SDL_init()时,FFmpeg2.3.3和SDL2-2.0.3的Android Media播放器出错。错误是关于SDL_main.h
- 使用Android Studio调试C ++库
- 如何将http C库正确包含到Android项目中()
- 如何调查随机Android原生函数调用错误()
- 从Android Activity onCreate方法调用QCoreApplication方法
- 如何使用/合并CPP文件到Android项目()
- Android JNI - 调用AttachCurrentThread而不使用DetachCurrentThread
- 如何加载android系统本机库