从 OpenGL glReadPixels 获取数据(使用 Pyglet)

发布于 2024-07-09 22:43:25 字数 279 浏览 14 评论 0原文

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

I'm using Pyglet(and OpenGL) in Python on an application, I'm trying to use glReadPixels to get the RGBA values for a set of pixels. It's my understanding that OpenGL returns the data as packed integers, since that's how they are stored on the hardware. However for obvious reasons I'd like to get it into a normal format for working with. Based on some reading I've come up with this: http://dpaste.com/99206/ , however it fails with an IndexError. How would I go about doing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

失退 2024-07-16 22:43:25

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

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

要测试这一点,请在 Pyglet“opengl.py” 示例中插入以下内容:

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

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

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.

黒涩兲箜 2024-07-16 22:43:25

我能够使用 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(...) 的输出与我在窗户里看到了。 (多重采样缓冲区丢失了?)

I was able to obtain the entire frame buffer using glReadPixels(...), then used the PIL to write out to a file:

# 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')

I was not interested in alpha, but I'm sure you could easily add it in.

I was forced to use glReadPixels(...), instead of the Pyglet code

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

because the output using save(...) was not identical to what I saw in the Window. (Multisampling buffers missed?)

遗失的美好 2024-07-16 22:43:25

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

You can use the PIL library, here is a code snippet which I use to capture such an image:

    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)

I guess including the alpha channel should be pretty straight forward (probably just replacing RGB with RGBA, but I have not tried that).

Edit: I wasn't aware that the pyglet OpenGL API is different from the PyOpenGL one. I guess one has to change the above code to use the buffer as the seventh argument (conforming to the less pythonic pyglet style).

我也只是我 2024-07-16 22:43:25

如果您阅读链接到的代码片段,您可以理解获取“正常”值的最简单方法就是以正确的顺序访问数组。
该片段看起来应该可以完成这项工作。 如果不行的话,调试一下看看问题出在哪里。

If you read the snippet you link to you can understand that the simplest and way to get the "normal" values is just accessing the array in the right order.
That snippet looks like it's supposed to do the job. If it doesn't, debug it and see what's the problem.

鹤仙姿 2024-07-16 22:43:25

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

On further review I believe my original code was based on some C specific code that worked because the array is just a pointer, so my using pointer arithmetic you could get at specific bytes, that obviously doesn't translate to Python. Does anyone how to extract that data using a different method(I assume it's just a matter of bit shifting the data).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文