我正在使用Java端直接nio缓冲区,它从位图中保存像素数据,并在NDK侧将其用作gl纹理。基本上我无法在c / c ++ gl绘制调用中正确读取Java nio缓冲区像素。
看起来Java端填充像素的Java.ByteBuffer与NDK端gl不直接兼容,后者需要无符号字节(java字节显然是32位)
Java端的单个白色像素:
int size = 1;
ByteBuffer vv = ByteBuffer.allocateDirect(size_t*4);
vv.order(ByteOrder.nativeOrder());
vv.put((byte)255); // R
vv.put((byte)255); // G
vv.put((byte)255); // B
vv.put((byte)255); // A
vv.position(0);
... //code to send the buffer address to JNI/NDK gl side
... //
将在NDK侧绘制为黑色像素;
我意识到这个缓冲区的实际无符号字节值可能是负数 - 我该如何纠正这个问题。 另外 - 一旦我解决了这个问题,我需要转换byte [],它是从Java端的Bitmap派生的图像数据,用于NDK侧纹理。
提前致谢!
答案 0 :(得分:0)
Java中的第一个“字节”是8位(有符号)而不是32位。 我不使用nio.ByteBufffer(尽管可以)。 byte []数组工作得更好更简单。
AndroidBitmap.java中的
public class AndroidBitmap {
public static native void updateBitmap(android.graphics.Bitmap bitmap, byte[] data, int w, int h, int bpp);
}
AndroidBitmap.c中的
jboolean Java_jni_AndroidBitmap_updateBitmap(JNIEnv* env, jobject that, jobject bitmap, jbyteArray data, jint w, jint h, jint bpp) {
jbyte* a = (*env)->GetByteArrayElements(env, data, NULL);
jsize bytes = (*env)->GetArrayLength(env, data);
AndroidBitmapInfo info = {0};
int r = AndroidBitmap_getInfo(env, bitmap, &info);
if (r != 0) {
// … "AndroidBitmap_getInfo() failed ! error=%d", r
return false;
}
int width = info.width;
int height = info.height;
if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888 && info.format != ANDROID_BITMAP_FORMAT_A_8) {
// "Bitmap format is not RGBA_8888 or A_8"
return false;
}
int bytesPerPixel = info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 ? 4 : 1;
void* pixels = null;
r = AndroidBitmap_lockPixels(env, bitmap, &pixels);
if (r != 0) {
// ..."AndroidBitmap_lockPixels() failed ! error=%d", r
return false;
}
if (w == width && h == height && bytesPerPixel == bpp) {
memcpy(pixels, a, width * height * bytesPerPixel);
} else if (bytesPerPixel == 4 && bpp == 1) {
grayscaleToRGBA(pixels, &info, data, w, h);
} else {
assertion(bytesPerPixel == 4 && bpp == 1, "only grayscale -> RGBA is supported bytesPerPixel=%d bpp=%d", bytesPerPixel, bpp);
}
AndroidBitmap_unlockPixels(env, bitmap);
(*env)->ReleaseByteArrayElements(env, data, a, 0);
return true;
}
希望这会有所帮助。