android: 如何通过更新 Surface 缓冲区从 ndk 更新 SurfaceView?
android: how to Update a SurfaceView from the ndk by updating the Surface buffer?
我正在从事图像处理项目。我有一个 SurfaceView
,我想在其中显示 "images" 从 jni 端。
我按照这个 blog , NDK ANativeWindow API 指令获取缓冲区的指针并从 C 端更新。
我得到了 运行 的代码,但我的 SurfaceView 没有更新(没有显示任何图像...)。更新缓冲区时也不会调用回调 surfaceChanged
。
这是我正在做的事情:
JNI 端:
/*
* Class: com_example_myLib
* Method: renderImage
* Signature: (JI)V
*/
JNIEXPORT void JNICALL com_example_myLib_renderImage
(JNIEnv *mJNIEnv, jobject mjobject, jobject javaSurface) {
#ifdef DEBUG_I
LOGI("renderImage attempt !");
#endif
// load an ipl image. code tested and works well with ImageView.
IplImage *iplimage = loadMyIplImage();
int iplImageWidth = iplimage->width;
int iplImageHeitgh = iplimage->height;
char * javalBmpPointer = malloc(iplimage->width * iplimage->height * 4);
int _javaBmpRowBytes = iplimage->width * 4;
// code tested and works well with ImageView.
copyIplImageToARGBPointer(iplimage, javalBmpPointer, _javaBmpRowBytes,
iplimage->width, iplimage->height);
#ifdef DEBUG_I
LOGI("ANativeWindow_fromSurface");
#endif
ANativeWindow* window = ANativeWindow_fromSurface(env, javaSurface);
#ifdef DEBUG_I
LOGI("Got window %p", window);
#endif
if(window != 0 ){
ANativeWindow_Buffer buffer;
if (ANativeWindow_lock(window, &buffer, NULL) == 0) {
#ifdef DEBUG_I
LOGI("GANativeWindow_lock %p", buffer);
#endif
memcpy(buffer.bits, javalBmpPointer, iplimage->width* iplimage->height* 4); // ARGB_8888
ANativeWindow_unlockAndPost(window);
}
ANativeWindow_release(window);
}
}
java 边:
// every time that I want to reload the image:
renderImage(mySurfaceView.getHolder().getSurface());
感谢您的宝贵时间和帮助!
导致空白 SurfaceView 的最常见问题之一是为视图设置背景。视图内容旨在成为透明的 "hole",仅用于布局。 Surface 内容位于视图层下方的单独层上,因此只有在视图保持透明时它们才可见。
View 背景通常应该被禁用,并且在 View 上不绘制任何东西,除非你想要某种 "mask" 效果(比如圆角)。
我正在从事图像处理项目。我有一个 SurfaceView
,我想在其中显示 "images" 从 jni 端。
我按照这个 blog , NDK ANativeWindow API 指令获取缓冲区的指针并从 C 端更新。
我得到了 运行 的代码,但我的 SurfaceView 没有更新(没有显示任何图像...)。更新缓冲区时也不会调用回调 surfaceChanged
。
这是我正在做的事情:
JNI 端:
/*
* Class: com_example_myLib
* Method: renderImage
* Signature: (JI)V
*/
JNIEXPORT void JNICALL com_example_myLib_renderImage
(JNIEnv *mJNIEnv, jobject mjobject, jobject javaSurface) {
#ifdef DEBUG_I
LOGI("renderImage attempt !");
#endif
// load an ipl image. code tested and works well with ImageView.
IplImage *iplimage = loadMyIplImage();
int iplImageWidth = iplimage->width;
int iplImageHeitgh = iplimage->height;
char * javalBmpPointer = malloc(iplimage->width * iplimage->height * 4);
int _javaBmpRowBytes = iplimage->width * 4;
// code tested and works well with ImageView.
copyIplImageToARGBPointer(iplimage, javalBmpPointer, _javaBmpRowBytes,
iplimage->width, iplimage->height);
#ifdef DEBUG_I
LOGI("ANativeWindow_fromSurface");
#endif
ANativeWindow* window = ANativeWindow_fromSurface(env, javaSurface);
#ifdef DEBUG_I
LOGI("Got window %p", window);
#endif
if(window != 0 ){
ANativeWindow_Buffer buffer;
if (ANativeWindow_lock(window, &buffer, NULL) == 0) {
#ifdef DEBUG_I
LOGI("GANativeWindow_lock %p", buffer);
#endif
memcpy(buffer.bits, javalBmpPointer, iplimage->width* iplimage->height* 4); // ARGB_8888
ANativeWindow_unlockAndPost(window);
}
ANativeWindow_release(window);
}
}
java 边:
// every time that I want to reload the image:
renderImage(mySurfaceView.getHolder().getSurface());
感谢您的宝贵时间和帮助!
导致空白 SurfaceView 的最常见问题之一是为视图设置背景。视图内容旨在成为透明的 "hole",仅用于布局。 Surface 内容位于视图层下方的单独层上,因此只有在视图保持透明时它们才可见。
View 背景通常应该被禁用,并且在 View 上不绘制任何东西,除非你想要某种 "mask" 效果(比如圆角)。