2015-11-19 62 views
1

我從C++獲取圖像數據,並且我想使用JNI將它傳遞給Java。 我的代碼如下:BufferedImage緩衝區大小錯誤

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()); 

正如我創建相同的大小和顏色格式爲C++圖像BufferedImage,我希望它具有相同大小的緩衝區。

然而,越來越java.lang.ArrayIndexOutOfBoundsException後,我開始進行調查,發現BufferedImage的緩衝區的大小(像素在我的代碼變量)是4倍以下則需要。有人可能會說GetArrayLength返回了一些元素,而不是字節,但是因爲我使用的是jbytearray,所以它應該與字節數相同。無論如何,我不應該得到一個例外。但是我願意。

對於100x100的32bpp的圖像,我的C++圖像緩衝器是正確100 * 100 * 4 = 40000尺寸的,但是當我打電話

new BufferedImage(100,100, TYPE_INT_ARGB) 

我得到緩衝區大小(sz in my code)等於10000.

這是爲什麼?我錯過了什麼(可能很明顯)?

+0

每個int四個字節? – EJP

+0

是的,我在32位Linux平臺上 – Flot2011

+0

另外,它是Java,所以它總是4個字節。 – Flot2011

回答

0

我的問題解決了,當我用另一種顏色類型,TYPE_4BYTE_ABGR,而不是TYPE_INT_ARGB。我看不出它如何影響一個緩衝區大小,因爲兩者都是,根據文檔:

an image with 8-bit RGBA color components 

但是我現在得到一個正確的緩衝區大小。 我會嘗試調查更多,並會在找到解釋後發佈更新。