2011-11-03 85 views
4

我有一些代码初始化OpenGL以呈现给java.awt.Canvas。 问题是,我无法弄清楚如何获得画布的缓冲区并将其变为BufferedImage。Java/OpenGL:获取画布的图像作为缓冲图像

我已经尝试覆盖getGraphics(),克隆光栅,并用自定义替换CanvasPeer。

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

我使用LWJGL代码设置父:

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

我也想知道这个答案。 – jli

回答

5

您需要将数据从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; 
} 
+0

谢谢!现在尝试一下。 – jli

0

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

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