Java / OpenGL:将一个画布的图像作为一个BufferedImage [英] Java / OpenGL: Getting the image of a Canvas as a BufferedImage
问题描述
我有一些代码初始化OpenGL来渲染到java.awt.Canvas。
问题是,我不知道如何获得画布的缓冲区并将其转换为BufferedImage。
I've got some code that initializes OpenGL to render to a java.awt.Canvas. The problem is, I can't figure out how I can get the buffer of the canvas and turn it into a BufferedImage.
我试过覆盖getGraphics(),克隆Raster,并用自定义的CanvasPeer替换。
I've tried overriding getGraphics(), cloning the Raster, and replacing the CanvasPeer with a custom one.
我猜OpenGL不以任何方式使用java图形,我可以获得OpenGL的缓冲区并将其转换为BufferedImage吗?
I'm guessing OpenGL doesn't use java graphics in any way then, so how can I get OpenGL's buffer and convert it into a BufferedImage?
我使用LWJGL的代码设置父级:
I am using LWJGL's code for setting parent:
Display.setParent(display_parent);
Display.create();
推荐答案
您需要从OpenGL缓冲区复制数据。我使用这种方法:
You need to copy data from OpenGL buffer. I was using this method:
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示例。
You need to use something similar according to your OpenGL wrapper. This is JOGL example.
这里是LWJGL包装器:
And here for LWJGL wrapper:
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;
}
EDIT
这也可能是有用的(它不完全是我的,应该调整):
This may be useful also (it's not fully mine, should be tuned too):
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;
}
这篇关于Java / OpenGL:将一个画布的图像作为一个BufferedImage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!