PIL Image.fromstring 从 PyOpengl 缓冲区获取的大小不正确

4 投票
2 回答
2060 浏览
提问于 2025-04-16 23:52

我用PyOpenGL来绘制一个2D图像。然后我想用Python图像库(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窗口中的样子,应该是这样的

而这是保存后的图像样子 而这是保存后的图像样子

2 个回答

0

你需要注意的是,在OpenGL中,坐标系统的起点和PIL是不一样的。可以看看这个链接

1

我自己解决了这个问题。

首先,我尝试了一个可能对遇到类似问题的人有帮助的解决方案:解决方案1

但是,经过大量的尝试和错误,我发现其实解决办法简单得多。

我只需要把两行代码的位置调换一下,从:

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

变成

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

显然,窗口的大小必须在创建窗口之前设置好。

撰写回答