代码之家  ›  专栏  ›  技术社区  ›  Crazy Redd

如何从LWJGL显示器写入视频文件?

  •  4
  • Crazy Redd  · 技术社区  · 10 年前

    因此,我学会了如何通过读取GL_FRONT中的字节缓冲区来截取LWJGL显示器的屏幕截图:

    public static void takeScreenShot(){
        GL11.glReadBuffer(GL11.GL_FRONT);
        int width = Display.getDisplayMode().getWidth();
        int height = Display.getDisplayMode().getHeight();
        int bpp = 4;
        ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * bpp);
        GL11.glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_NSIGNED_BYTE, buffer);
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss");
        Date date = new Date();
        String datetime = dateFormat.format(date);
        File file = new File(screenshot_dir + "\\" + datetime + ".png");
        String format = "PNG";
        BufferedImage image = new BufferedImage(width, height, Bufferedmage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                int i = (x + (width * y)) * bpp;
                int r = buffer.get(i) & 0xFF;
                int g = buffer.get(i + 1) & 0xFF;
                int b = buffer.get(i + 2) & 0xFF;
                image.setRGB(x, height - (y + 1), (0xFF << 24) | (r << 16) | (g << 8) | );
            }
        }
        try {
            ImageIO.write(image, format, file);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    我假设我可以保持每秒从前缓冲区读取大约60次(我知道这会大大降低性能)。然后,我可以将一定数量的帧写入一个缓冲区,当它满了时,它将被交换到另一个。缓冲区已满后,其内容可以附加到文件中。

    如何将字节缓冲区格式化为视频中的帧?

    非常感谢。

    1 回复  |  直到 10 年前
        1
  •  2
  •   eliaspr    8 年前

    你的问题确实很老,但为了完整起见,我无论如何都会回答。

    我的答案是 太大了 提供示例或解释。这就是为什么我会链接别人的教程和官方文档。

    1. 将场景(或其他)渲染为2D纹理。( http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture/ )
    2. 使用检索纹理数据 glGetTexImage ( https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glGetTexImage.xhtml )
    3. 下载用于编码MP4(或任何您想要的)的Java Library,并逐帧编码。

    下面是一些伪代码:

    create framebuffer
    enable framebuffer
    for all frames {
        render to framebuffer
        glGetTexImage(...)
        library.encodeFrame(imageData)
    }
    

    这是非常普遍的,它在很大程度上取决于您用于编码的库。

    推荐文章