我正在用 Java 创建一个程序,它将与 C 库接口以从硬件获取图像并使用 OpenGL(使用 JOGL)显示。所以工作流程是这样的:
Hardware -> C -> disk image file -> Java -> JOGL
我的Java -> JOGL
部分工作正常。图像完全显示,我可以一次加载多个图像。我也有Hardware -> C
工作,C 中的一个临时查看器显示图像创建得很好。
问题的症结在于:我希望能够main()
在 C 中启动 Java 程序的方法,然后仅使用 C 中的 JNI 代码显示图像(使用我创建的静态方法)。但是,当我这样做时,图像会被截断,我只能得到前 20 行左右。我知道我正在加载整个图像,因为我可以检查图像中每个像素的像素值。只有显示被截断。我加载的每张图像都显示相同数量的像素。
简而言之,这是 C 代码:
int main () { ...
HMODULE * jvm_dll;
//HWND hWnd = GetConsoleWindow();
//ShowWindow( hWnd, SW_HIDE );
env = create_vm(&jvm, jvm_dll);
if (env == NULL) { return 1; }
//Create a new String array with one blank String
cls = (*env)->FindClass(env,"java/lang/String");
arg = (*env)->NewStringUTF(env,"");
args = (jobjectArray)(*env)->NewObjectArray(env, 1, cls, arg);
//Call the main method with the String array argument
cls = (*env)->FindClass(env, "path/to/package/program");
mID = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V");
(*env)->CallStaticVoidMethod(env, cls, mID, args);
PrintStackTrace(env);
blockAndClose(jvm, env, jvm_dll);
return ret;
}
int blockAndClose() {...
int ret = 0;
if (jvm == 0 || env == 0) {
FreeLibrary(*jvm_dll);
return 1;
}
ret = (*jvm)->DestroyJavaVM(jvm);
if(jvm_dll) {
FreeLibrary(*jvm_dll);
jvm_dll = 0;
}
env = 0;
jvm = 0;
return ret;
}
我知道我只发布了 C 部分,但是当我纯粹在 Java 中运行 Java 部分时它正在工作。在这一点上,C 部分只是一个“启动器”,所以我想知道为什么它会影响代码的运行。有什么建议么?
编辑:
这是加载图像的代码。我使用 JAI 将图像作为PlanarImage
类型加载(TiledImage
类是子类)。
tempI = JAI.create("fileload", path);
DataBufferUShort dbOut = null;
ColorModel CM = PlanarImage.getDefaultColorModel(DataBuffer.TYPE_USHORT, tempI.getNumBands());
SampleModel SM = CM.createCompatibleSampleModel(tempI.getWidth(), tempI.getHeight());
//Ensure that the buffer is in the internal format (USHORT)
if (tempI.getData().getDataBuffer().getDataType() != DataBuffer.TYPE_USHORT) {
DataBuffer dBIn = tempI.getData().getDataBuffer();
short [] dBPixels = new short[dBIn.getSize()];
switch(dBIn.getDataType()) {
case DataBuffer.TYPE_BYTE:
DataBufferByte dBByte = (DataBufferByte)dBIn;
byte [] pByte = dBByte.getData();
for (int b = 0; b < pByte.length; b++)
{ dBPixels[b] = (short)((double)pByte[b] / 0xFF * 0xFFFF); }
dbOut = new DataBufferUShort(dBPixels, dBPixels.length);
break;
case DataBuffer.TYPE_SHORT:
DataBufferShort dBShort = (DataBufferShort)dBIn;
dBPixels = dBShort.getData();
dbOut = new DataBufferUShort(dBPixels, dBPixels.length);
break;
} //SWITCH DATA TYPE --END
WritableRaster rs = Raster.createWritableRaster(SM, dbOut, new Point(0,0));
tempI = new TiledImage(0,0,tempI.getWidth(),tempI.getHeight(),0,0,SM,CM);
((TiledImage)tempI).setData(rs);
}