17

I'm currently having trouble creating an image from a binary string of data in my Python program. I receive the binary data via a socket but when I try the methods I read about in Imaging Library Handbook like this:

buff = StringIO.StringIO() #buffer where image is stored
#Then I concatenate data by doing a 
buff.write(data) #the data from the socket
im = Image.open(buff)

I get an exception to the effect of "image type not recognized". I know that I am receiving the data correctly because if I write the image to a file and then open a file it works:

buff = StringIO.StringIO() #buffer where image is stored
buff.write(data) #data is from the socket
output = open("tmp.jpg", 'wb')
output.write(buff)
output.close()
im = Image.open("tmp.jpg")
im.show()

I figure I am probably doing something wrong in using the StringIO class but I'm not sure

1
  • 1
    In reply to your comment about StringIO being documented: The idea of StringIO is that it's just an in-memory file. The behavior would be the same on a normal on-disk file if you called file.write('...'), then file.read() without seeking back to the beginning. Try it out :) Commented Nov 4, 2009 at 0:11

2 Answers 2

29

I suspect that you're not seek-ing back to the beginning of the buffer before you pass the StringIO object to PIL. Here's some code the demonstrates the problem and solution:

>>> buff = StringIO.StringIO()
>>> buff.write(open('map.png', 'rb').read())
>>> 
>>> #seek back to the beginning so the whole thing will be read by PIL
>>> buff.seek(0)
>>>
>>> Image.open(buff)
<PngImagePlugin.PngImageFile instance at 0x00BD7DC8>
>>> 
>>> #that worked.. but if we try again:
>>> Image.open(buff)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\python25\lib\site-packages\pil-1.1.6-py2.5-win32.egg\Image.py", line 1916, in open
    raise IOError("cannot identify image file")
IOError: cannot identify image file

Make sure you call buff.seek(0) before reading any StringIO objects. Otherwise you'll be reading from the end of the buffer, which will look like an empty file and is likely causing the error you're seeing.

Sign up to request clarification or add additional context in comments.

3 Comments

I'll give that a try tomorrow! Thanks for the idea
Thanks for the input. The StringIO module is not well documented (at least that I could find)
You could instead do buff = StringIO.StringIO(open('map.png', 'rb').read()). No need to seek() anymore.
7

You have either call buff.seek(0) or, better, initialize memory buffer with data StringIO.StringIO(data).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.