BufferedImage 缓冲区大小错误
BufferedImage wrong buffer size
我正在从 C++ 获取图像数据,我想使用 JNI 将其传递给 Java。
我的代码如下:
jclass bitmap_class = (jclass) env->FindClass("java/awt/image/BufferedImage");
jclass raster_class = (jclass) env->FindClass("java/awt/image/WritableRaster");
jclass data_class = (jclass) env->FindClass("java/awt/image/DataBufferByte");
jmethodID constructor = env->GetMethodID(bitmap_class, "<init>", "(III)V");
int w = nativeFrame->Width();
int h = nativeFrame->Height();
int t = 2; // That is TYPE_INT_ARGB
jobject bitmap = env->NewObject(bitmap_class, constructor, w, h, t);//byteType);
jmethodID getRaster = env->GetMethodID(bitmap_class, "getRaster", "()Ljava/awt/image/WritableRaster;");
jobject raster = env->CallObjectMethod(bitmap, getRaster);
jmethodID getDataBuffer = env->GetMethodID(raster_class, "getDataBuffer", "()Ljava/awt/image/DataBuffer;");
jobject dataBuffer = env->CallObjectMethod(raster, getDataBuffer);
jmethodID getData = env->GetMethodID(data_class, "getData", "()[B");
jobject pixelsObject = env->CallObjectMethod(dataBuffer, getData);
jbyteArray pixels = (jbyteArray)pixelsObject;
long sz = env->GetArrayLength(pixels);
env->SetByteArrayRegion(pixels, (jsize)0, (jsize)nativeFrame->BufferSize(), (jbyte*) nativeFrame->GetData());
当我创建 BufferedImage
与 c++ 图像具有相同大小和颜色格式时,我希望它具有相同大小的缓冲区。
但是,在得到 java.lang.ArrayIndexOutOfBoundsException 之后,我开始调查并发现 BufferedImage
的缓冲区大小(我代码中的 pixels 变量)比 少 4 倍 然后需要。有人可能会说 GetArrayLength
returns 是一些元素,而不是字节,但我使用的是 jbytearray
,它应该是相同的字节数。无论如何,我不应该例外。但是我有。
示例
对于 100x100 32bpp 图像,我的 C++ 图像缓冲区的大小是正确的 100*100*4=40000,但是当我调用
new BufferedImage(100,100, TYPE_INT_ARGB)
我得到的缓冲区大小(sz 在我的代码中)等于 10000。
这是为什么?我错过了什么(可能很明显)?
当我使用另一种颜色类型 TYPE_4BYTE_ABGR
而不是 TYPE_INT_ARGB
时,我的问题就解决了。根据文档,我看不出它如何影响缓冲区大小,因为两者都是:
an image with 8-bit RGBA color components
但是我现在得到了正确的缓冲区大小。
我将尝试进行更多调查,并在找到解释后 post 进行更新。
我正在从 C++ 获取图像数据,我想使用 JNI 将其传递给 Java。 我的代码如下:
jclass bitmap_class = (jclass) env->FindClass("java/awt/image/BufferedImage");
jclass raster_class = (jclass) env->FindClass("java/awt/image/WritableRaster");
jclass data_class = (jclass) env->FindClass("java/awt/image/DataBufferByte");
jmethodID constructor = env->GetMethodID(bitmap_class, "<init>", "(III)V");
int w = nativeFrame->Width();
int h = nativeFrame->Height();
int t = 2; // That is TYPE_INT_ARGB
jobject bitmap = env->NewObject(bitmap_class, constructor, w, h, t);//byteType);
jmethodID getRaster = env->GetMethodID(bitmap_class, "getRaster", "()Ljava/awt/image/WritableRaster;");
jobject raster = env->CallObjectMethod(bitmap, getRaster);
jmethodID getDataBuffer = env->GetMethodID(raster_class, "getDataBuffer", "()Ljava/awt/image/DataBuffer;");
jobject dataBuffer = env->CallObjectMethod(raster, getDataBuffer);
jmethodID getData = env->GetMethodID(data_class, "getData", "()[B");
jobject pixelsObject = env->CallObjectMethod(dataBuffer, getData);
jbyteArray pixels = (jbyteArray)pixelsObject;
long sz = env->GetArrayLength(pixels);
env->SetByteArrayRegion(pixels, (jsize)0, (jsize)nativeFrame->BufferSize(), (jbyte*) nativeFrame->GetData());
当我创建 BufferedImage
与 c++ 图像具有相同大小和颜色格式时,我希望它具有相同大小的缓冲区。
但是,在得到 java.lang.ArrayIndexOutOfBoundsException 之后,我开始调查并发现 BufferedImage
的缓冲区大小(我代码中的 pixels 变量)比 少 4 倍 然后需要。有人可能会说 GetArrayLength
returns 是一些元素,而不是字节,但我使用的是 jbytearray
,它应该是相同的字节数。无论如何,我不应该例外。但是我有。
示例
对于 100x100 32bpp 图像,我的 C++ 图像缓冲区的大小是正确的 100*100*4=40000,但是当我调用
new BufferedImage(100,100, TYPE_INT_ARGB)
我得到的缓冲区大小(sz 在我的代码中)等于 10000。
这是为什么?我错过了什么(可能很明显)?
当我使用另一种颜色类型 TYPE_4BYTE_ABGR
而不是 TYPE_INT_ARGB
时,我的问题就解决了。根据文档,我看不出它如何影响缓冲区大小,因为两者都是:
an image with 8-bit RGBA color components
但是我现在得到了正确的缓冲区大小。 我将尝试进行更多调查,并在找到解释后 post 进行更新。