0

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

4

5 回答 5

4

You must first create an array of the correct type, then pass it to glReadPixels:

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

To test this, insert the following in the Pyglet "opengl.py" example:

@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]

Now you should see the color code for the pixel under the mouse cursor whenever you click somewhere in the app window.

于 2009-02-08T10:01:06.650 回答
2

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

# 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 代码

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

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

于 2010-11-08T08:36:50.420 回答
1

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

    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 API 不同。我想必须更改上面的代码以使用缓冲区作为第七个参数(符合较少的 pythonic pyglet 样式)。

于 2008-12-15T12:31:41.607 回答
0

在进一步的审查中,我相信我的原始代码是基于一些有效的 C 特定代码,因为数组只是一个指针,所以我使用指针算法可以获得特定字节,这显然不会转换为 Python。有谁如何使用不同的方法提取该数据(我认为这只是对数据进行位移的问题)。

于 2008-12-15T18:47:00.957 回答
0

如果您阅读链接到的代码段,您可以理解获得“正常”值的最简单方法就是以正确的顺序访问数组。
该片段看起来应该完成这项工作。如果没有,请调试它并查看问题所在。

于 2008-12-15T08:30:21.140 回答