Java / OpenGL:将Canvas的图像作为BufferedImage

我有一些代码初始化OpenGL以呈现给java.awt.Canvas。 问题是,我无法弄清楚如何获取canvas的缓冲区并将其转换为BufferedImage。

我已经尝试重写getGraphics(),克隆Raster,并用自定义替换CanvasPeer。

我猜测OpenGL不会以任何方式使用java图形,那么我如何获得OpenGL的缓冲区并将其转换为BufferedImage?

我正在使用LWJGL的代码来设置父级:

Display.setParent(display_parent); Display.create(); 

您需要从OpenGL缓冲区复制数据。 我正在使用这种方法:

 FloatBuffer grabScreen(GL gl) { int w = SCREENWITDH; int h = SCREENHEIGHT; FloatBuffer bufor = FloatBuffer.allocate(w*h*4); // 4 = rgba gl.glReadBuffer(GL.GL_FRONT); gl.glReadPixels(0, 0, w, h, GL.GL_RGBA, GL.GL_FLOAT, bufor); //Copy the image to the array imageData return bufor; } 

您需要根据OpenGL包装器使用类似的东西。 这是JOGL的例子。

这里是LWJGL包装器:

 private static synchronized byte[] grabScreen() { int w = screenWidth; int h = screenHeight; ByteBuffer bufor = BufferUtils.createByteBuffer(w * h * 3); GL11.glReadPixels(0, 0, w, h, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, bufor); //Copy the image to the array imageData byte[] byteimg = new byte[w * h * 3]; bufor.get(byteimg, 0, byteimg.length); return byteimg; } 

编辑

这也许有用(它不完全是我的,也应该调整):

 BufferedImage toImage(byte[] data, int w, int h) { if (data.length == 0) return null; DataBuffer buffer = new DataBufferByte(data, w * h); int pixelStride = 3; //assuming r, g, b, skip, r, g, b, skip... int scanlineStride = 3 * w; //no extra padding int[] bandOffsets = { 0, 1, 2 }; //r, g, b WritableRaster raster = Raster.createInterleavedRaster(buffer, w, h, scanlineStride, pixelStride, bandOffsets, null); ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB); boolean hasAlpha = false; boolean isAlphaPremultiplied = true; int transparency = Transparency.TRANSLUCENT; int transferType = DataBuffer.TYPE_BYTE; ColorModel colorModel = new ComponentColorModel(colorSpace, hasAlpha, isAlphaPremultiplied, transparency, transferType); BufferedImage image = new BufferedImage(colorModel, raster, isAlphaPremultiplied, null); AffineTransform flip; AffineTransformOp op; flip = AffineTransform.getScaleInstance(1, -1); flip.translate(0, -image.getHeight()); op = new AffineTransformOp(flip, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); image = op.filter(image, null); return image; } 

我不认为这对你的情况是可能的,这就是为什么:

LWJGL不直接绘制到canvas(至少不在Windows中)。 canvas仅用于获取窗口句柄,以作为OpenGL的父窗口。 因此,canvas永远不会被直接绘制。 要捕获内容,您可能不得不求助于屏幕截图。