PIL Image.fromstring from PyOpengl buffer has the wrong size
I use PyOpenGL to draw a 2D Image. Then I want to use the Python Imaging Library (PIL) to store this image to disk. I use GLUT to display the image which works perfectly. But when I use PIL to store th开发者_JAVA百科e image it extracts the wrong clipping. It has the wrong size.
Here is a minimal example which reproduces the effect and I also attach the output to make it more clear without running some code.
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 ()
this is how it looks int the GLUT window and how it is supposed to look like
and this is how the saved image looks likeI managed to solve my own Problem.
First I tried the following solution which might also help people with related problems: solution1
But then, through extensive trial and error, I found that the solution is much simpler.
I simply had to swap two lines from:
glutCreateWindow("Draw Polygons")
glutInitWindowSize(width, height)
to
glutInitWindowSize(width, height)
glutCreateWindow("Draw Polygons")
Apparently the size has to be set before the window
You should consider that in OpenGL the coordinate system starts at different place than in PIL. Look at this.
精彩评论