Reputation: 2419
I tried encoding an image and decoding the same in python shell. The first time I open the decoded base64 string in PIL there is no error, if I repeat the Image.open() command I'm getting IOError: cannot identify image file.
>>> with open("/home/home/Desktop/gatherify/1.jpg", "rb") as image_file:
... encoded_string = base64.b64encode(image_file.read())
>>> image_string = cStringIO.StringIO(base64.b64decode(encoded_string))
>>> img = Image.open(image_string)
>>> img
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=576x353 at 0xA21F20C>
>>> img.show() <-- Image opened without any errors.
>>> img = Image.open(image_string)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/lib/python2.6/dist-packages/PIL/Image.py", line 1980, in open
raise IOError("cannot identify image file")
IOError: cannot identify image file
Why is this happening?
Upvotes: 4
Views: 1966
Reputation: 368894
image_string
is file-like object. File-like object has file position.
Once the file is read, the position is advanced.
Any subsequent is occurred at that position unless you explicitly position it using seek
method.
So if you want to reopen the file:
...
image_string.seek(0) # reset file position to the beginning of the file.
img = Image.open(image_string)
Upvotes: 1
Reputation: 4976
When you create your image_string
, you're creating a fake file-like object backed by a string. When you call Image.open
, it reads this fake file, moving the file pointer to the end of the file. Attempting to use Image.open
on it again just gives you an EOF.
You need to either re-create your StringIO
object, or seek()
to the beginning of the stream.
Upvotes: 4