我在应用程序的 Python 中使用 Pyglet(和 OpenGL),我正在尝试使用 glReadPixels 来获取一组像素的 RGBA 值。我的理解是 OpenGL 将数据作为打包整数返回,因为这就是它们在硬件上的存储方式。但是,出于显而易见的原因,我想将其转换为正常格式以供使用。根据一些阅读,我想出了这个:http ://dpaste.com/99206/ ,但是它失败并出现 IndexError。我该怎么做呢?
5 回答
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.
我能够使用 获取整个帧缓冲区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(...)
与我在窗口中看到的不同。(错过了多重采样缓冲区?)
您可以使用 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 样式)。
在进一步的审查中,我相信我的原始代码是基于一些有效的 C 特定代码,因为数组只是一个指针,所以我使用指针算法可以获得特定字节,这显然不会转换为 Python。有谁如何使用不同的方法提取该数据(我认为这只是对数据进行位移的问题)。
如果您阅读链接到的代码段,您可以理解获得“正常”值的最简单方法就是以正确的顺序访问数组。
该片段看起来应该完成这项工作。如果没有,请调试它并查看问题所在。