0

I want to use an string for storing image data.

Background: In some other parts of the code I load Images, which were downloaded from the web, and stored as string using

imgstr = urllib2.urlopen(imgurl).read()
PIL.Image.open(StringIO.StringIO(imstr))

Now I do some image manipulations with an 'PIL.Image' object. I also want to convert these objects in the same string-format so that they can be used in the original code.

This is what I tried.

>>> import PIL
>>> import StringIO

>>> im = PIL.Image.new("RGB", (512, 512), "white")
>>> imstr=im.tostring()

>>> newim=PIL.Image.open(StringIO.StringIO(imstr))
Traceback (innermost last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\site-packages\PIL\Image.py", line 2006, in open
    raise IOError("cannot identify image file")
IOError: cannot identify image file

I found hints in the web, that this might happen. e.g Python PIL: how to write PNG image to string However I couldn't extract the correct solution for my sample code.

Next try was:

>>> imstr1 = StringIO.StringIO()
>>> im.save(imstr1,format='PNG')
>>> newim=PIL.Image.open(StringIO.StringIO(imstr1))
Traceback (innermost last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\site-packages\PIL\Image.py", line 2006, in open
    raise IOError("cannot identify image file")
IOError: cannot identify image file
Community
  • 1
  • 1
BerndGit
  • 1,530
  • 3
  • 18
  • 47
  • 1
    The `tostring()` method doesn't produce an image file format; it produces the *raw image data*. You can only load that again with `. What goal did you have in mind, save the image in a specific format to an in-memory file object? – Martijn Pieters Mar 26 '15 at 21:19
  • If so you want [Python PIL: how to write PNG image to string](http://stackoverflow.com/q/646286) – Martijn Pieters Mar 26 '15 at 21:20
  • Thank you for your extremly fast response. I have answered your questions, by editing my post. – BerndGit Mar 26 '15 at 21:34

1 Answers1

1

You don't have to wrap the existing StringIO object in another such object; imstr1 is already a file object. All you have to do is seek back to the start:

imstr1 = StringIO.StringIO()
im.save(imstr1, format='PNG')
imstr1.seek(0)
newim = PIL.Image.open(imstr1)

You can get the bytestring out of the StringIO object with the StringIO.getvalue() method:

imstr1 = StringIO.StringIO()
im.save(imstr1, format='PNG')
imagedata = imstr1.getvalue()

and then you can later load it back into a PIL.Image object in the opposite direction with:

newim = PIL.Image.open(StringIO.StringIO(imagedata))
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Thank you. This code is working. However I have to correct may question again. I found out that imstr should be a `string` object not a `StringIO` object. Kindly look at my edit above for more details. – BerndGit Mar 26 '15 at 21:51
  • @BerndGit: updated to show how to get the image data as a string. – Martijn Pieters Mar 26 '15 at 21:55