关于python:从OpenGL glReadPixels获取数据(使用Pyglet)

Get Data from OpenGL glReadPixels(using Pyglet)

我在应用程序上的Python中使用Pyglet(和OpenGL),我正在尝试使用glReadPixels获取一组像素的RGBA值。 据我了解,OpenGL将数据作为打包的整数返回,因为这是将它们存储在硬件上的方式。 但是出于明显的原因,我想将其转换为正常格式进行处理。 根据一些阅读,我提出了这个建议:http://dpaste.com/99206/,但是它失败并出现IndexError。 我将如何去做呢?


您必须首先创建正确类型的数组,然后将其传递给glReadPixels:

1
2
a = (GLuint * 1)(0)
glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_INT, a)

要对此进行测试,请在Pyglet" opengl.py"示例中插入以下内容:

1
2
3
4
5
@window.event
def on_mouse_press(x, y, button, modifiers):
    a = (GLuint * 1)(0)
    glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_INT, a)
    print a[0]

现在,每当您在应用程序窗口中的某个位置单击时,您都应该在鼠标光标下方看到像素的颜色代码。


我能够使用glReadPixels(...)获取整个帧缓冲区,然后使用PIL写入文件:

1
2
3
4
5
6
7
8
9
10
# Capture image from the OpenGL buffer
buffer = ( GLubyte * (3*window.width*window.height) )(0)
glReadPixels(0, 0, window.width, window.height, GL_RGB, GL_UNSIGNED_BYTE, buffer)

# Use PIL to convert raw RGB buffer and flip the right way up
image = Image.fromstring(mode="RGB", size=(window.width, window.height), data=buffer)    
image = image.transpose(Image.FLIP_TOP_BOTTOM)

# Save image to disk
image.save('jpap.png')

我对alpha不感兴趣,但是我敢肯定您可以轻松地添加它。

我被迫使用glReadPixels(...)而不是Pyglet代码

1
pyglet.image.get_buffer_manager().get_color_buffer().save('jpap.png')

因为使用save(...)的输出与我在Window中看到的输出不同。 (错过了多采样缓冲区?)


您可以使用PIL库,这是我用来捕获此类图像的代码段:

1
2
3
4
5
    buffer = gl.glReadPixels(0, 0, width, height, gl.GL_RGB,
                             gl.GL_UNSIGNED_BYTE)
    image = Image.fromstring(mode="RGB", size=(width, height),
                             data=buffer)
    image = image.transpose(Image.FLIP_TOP_BOTTOM)

我想包括Alpha通道应该很简单(可能只是用RGBA代替RGB,但我没有尝试过)。

编辑:我不知道pyglet OpenGL API与PyOpenGL有所不同。我猜想必须更改上面的代码以将缓冲区用作第七个参数(符合较少的pythonic pyglet样式)。


在进一步审查中,我相信我的原始代码基于某些C特定代码,因为该数组只是一个指针,因此可以工作,因此我使用指针算法可以得到特定的字节,这显然不会转换为Python。是否有人使用另一种方法提取数据(我假设这只是对数据进行位移的问题)。


如果您阅读了链接的片段,则可以理解,获取"正常"值的最简单方法就是按正确的顺序访问数组。
这段代码看起来像应该做的那样。如果不是,请对其进行调试,然后查看问题所在。