PIL Image.fromstring из буфера PyOpengl имеет неправильный размер

Я использую PyOpenGL для рисования 2D-изображения. Затем я хочу использовать Python Imaging Library (PIL) для сохранения этого изображения на диск. Я использую GLUT для отображения изображения, которое отлично работает. Но когда я использую PIL для хранения изображения, он извлекает неправильную обрезку. У него неправильный размер.

Вот минимальный пример, который воспроизводит эффект, и я также прикрепляю вывод, чтобы сделать его более понятным без запуска кода.

from OpenGL.GL import *
from OpenGL.GLUT import *
from PIL import Image

width, height = 640, 480

def DrawStuff():
    poly1 = [(0,0), (640,0), (0,480)]
    color = (0.5, 0.4, 0.3, 0.8)
    glClear(GL_COLOR_BUFFER_BIT)
    glPushMatrix()
    glLineWidth(5.0)

    glColor4f(*color)
    glBegin(GL_POLYGON)
    glVertex2f(poly1[0][0], poly1[0][1])
    glVertex2f(poly1[1][0], poly1[1][1])
    glVertex2f(poly1[2][0], poly1[2][1])    
    glVertex2f(poly1[0][0], poly1[0][1])
    glEnd() # GL_POLYGON

    glPopMatrix()
    glPixelStorei(GL_PACK_ALIGNMENT, 1)
    data = glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE)
    image = Image.fromstring("RGBA", (width, height), data)
    image.show()
    image.save('out.png', 'PNG')
    glutSwapBuffers()


# glut initialization
glutInit(sys.argv)
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA)
glutCreateWindow("Draw Polygons")
glutInitWindowSize(width, height)

# set the function to draw
glutDisplayFunc(DrawStuff)

# enable the alpha blending
glEnable(GL_BLEND)
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

# prepare for 2D drawing
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0, width, height, 0, 0, 1)
glDisable(GL_DEPTH_TEST)
glMatrixMode(GL_MODELVIEW)

# start the mainloop
glutMainLoop ()

вот как это выглядит в окне GLUT и как оно должно выглядетьвот как это выглядит в окне Окно GLUT и как оно должно выглядеть

и так выглядит сохраненное изображениеи так выглядит сохраненное изображение


person dedan    schedule 18.08.2011    source источник


Ответы (2)


Мне удалось решить свою собственную проблему.

Сначала я попробовал следующее решение, которое также может помочь людям со связанными проблемами: solution1

Но затем, путем долгих проб и ошибок, я обнаружил, что решение намного проще.

Мне просто пришлось поменять местами две строки из:

glutCreateWindow("Draw Polygons")
glutInitWindowSize(width, height)

to

glutInitWindowSize(width, height)
glutCreateWindow("Draw Polygons")

По-видимому, размер должен быть установлен перед окном

person dedan    schedule 19.08.2011

Вы должны учитывать, что в OpenGL система координат начинается в другом месте, чем в PIL. Посмотрите это.

person Mariy    schedule 18.08.2011
comment
спасибо за кислую помощь. Но проблема была не в нем. Я нашел решение, но не могу опубликовать его в качестве ответа, потому что у меня недостаточно репутации. Я отредактирую вопрос. - person dedan; 18.08.2011
comment
Это яркий пример того, почему ответы не должны основываться на ссылках для объяснения. Обратите внимание на мертвую ссылку. Обидно, поскольку вопрос (и, возможно, этот ответ) все еще актуален. - person ephsmith; 22.08.2012