4

I'm new to Python and PIL. I am trying to follow code samples on how to load an image into to Python through PIL and then draw its pixels using openGL. Here are some line of the code:

from Image import *
im = open("gloves200.bmp") 
pBits = im.convert('RGBA').tostring()

.....

glDrawPixels(200, 200, GL_RGBA, GL_UNSIGNED_BYTE, pBits)

This will draw a 200 x 200 patch of pixels on the canvas. However, it is not the intended image-- it looks like it is drawing pixels from random memory. The random memory hypothesis is supported by the fact that I get the same pattern even when I attempt to draw entirely different images.Can someone help me? I'm using Python 2.7 and the 2.7 version of pyopenGL and PIL on Windows XP.

screen shot

ahoffer
  • 6,347
  • 4
  • 39
  • 68

3 Answers3

9

I think you were close. Try:

pBits = im.convert("RGBA").tostring("raw", "RGBA")

The image first has to be converted to RGBA mode in order for the RGBA rawmode packer to be available (see Pack.c in libimaging). You can check that len(pBits) == im.size[0]*im.size[1]*4, which is 200x200x4 = 160,000 bytes for your gloves200 image.

Eryk Sun
  • 33,190
  • 5
  • 92
  • 111
1

Have you tried using the conversion inside the tostring function directly?

im = open("test.bmp")
imdata = im.tostring("raw", "RGBA", 0, -1)
w, h = im.size[0], im.size[1]
glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, imdata)

Alternatively use compatibility version:

 try:
      data = im.tostring("raw", "BGRA")
 except SystemError:
      # workaround for earlier versions
      r, g, b, a = im.split()
      im = Image.merge("RGBA", (b, g, r, a))
mikebabcock
  • 791
  • 1
  • 7
  • 20
  • The .tostring function gives me this error " return apply(encoder, (mode,) + args + extra) SystemError: unknown raw mode" when I run your code snippet. – ahoffer Jul 20 '11 at 05:36
  • Added a workaround found at http://www.java2s.com/Open-Source/Python/GUI/Python-Image-Library/Imaging-1.1.7/PIL/ImageQt.py.htm to my snippet above – mikebabcock Jul 20 '11 at 13:15
  • Thank you for the work-around. What is the compatibility issue. Was I running old sample code on newer version of the library? – ahoffer Jul 20 '11 at 18:38
0

Thank you for the help. Thanks to mikebabcock for updating the sample code on the Web. Thanks to eryksun for the code snippet-- I used it in my code.

I did find my error and it was Python newb mistake. Ouch. I declared some variables outside the scope of any function in the module and naively thought I was modifying their values inside a function. Of course, that doesn't work and so my glDrawPixels call was in fact drawing random memory.

ahoffer
  • 6,347
  • 4
  • 39
  • 68
  • I imported only the Image class from PIL. Now I do not get an error when I execute: pBits=im.convert('RGBA').tostring() I cannot figure out why. What there a namespace collision? Is tostring() some kind of global function or defined at the top of some class hierarchy? – ahoffer Jul 20 '11 at 20:53