Я использую Pyglet (и OpenGL) в Python в приложении, я пытаюсь использовать glReadPixels для получения значений RGBA для набора пикселей. Насколько я понимаю, OpenGL возвращает данные в виде упакованных целых чисел, поскольку именно так они хранятся на оборудовании. Однако по понятным причинам я хотел бы привести его в нормальный формат для работы. Основываясь на некоторых чтениях, я придумал следующее: http://dpaste.com/99206/ , однако он терпит неудачу с IndexError. Как мне это сделать?
Получить данные из OpenGL glReadPixels (используя Pyglet)
Ответы (5)
Вы должны сначала создать массив правильного типа, а затем передать его в 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]
Теперь вы должны видеть цветовой код пикселя под курсором мыши всякий раз, когда вы щелкаете где-нибудь в окне приложения.
a
как GLubyte
и использовать GL_UNSIGNED_BYTE
. Если вы используете их, выбранный цвет вернется в виде значений от 0 до 255 вместо непонятных long
s.
- person Thane Brimhall; 21.11.2013
Вы можете использовать библиотеку 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)
Я предполагаю, что включение альфа-канала должно быть довольно простым (возможно, просто заменить RGB на RGBA, но я этого не пробовал).
Изменить: я не знал, что API-интерфейс pyglet OpenGL отличается от PyOpenGL. Я предполагаю, что нужно изменить приведенный выше код, чтобы использовать буфер в качестве седьмого аргумента (в соответствии с менее питоническим стилем pyglet).
Я смог получить весь буфер кадра, используя 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')
Меня не интересовала альфа-версия, но я уверен, что вы могли бы легко добавить ее.
Я был вынужден использовать glReadPixels(...)
вместо кода Pyglet
pyglet.image.get_buffer_manager().get_color_buffer().save('jpap.png')
потому что вывод с использованием save(...)
не был идентичен тому, что я видел в окне. (Буферы мультисэмплинга пропущены?)
Если вы прочтете фрагмент кода, на который вы ссылаетесь, вы поймете, что самый простой способ получить «нормальные» значения — это просто получить доступ к массиву в правильном порядке.
Этот фрагмент выглядит так, как будто он должен выполнять свою работу. Если это не так, отладьте его и посмотрите, в чем проблема.
При дальнейшем рассмотрении я считаю, что мой исходный код был основан на некотором коде, специфичном для C, который работал, потому что массив - это просто указатель, поэтому моя арифметика с использованием указателя, которую вы могли бы получить в определенных байтах, что, очевидно, не переводится на Python. Кто-нибудь знает, как извлечь эти данные, используя другой метод (я предполагаю, что это просто вопрос битового сдвига данных).