30

For some reason, when I try to make an image from a BytesIO steam, it can't identify the image. Here is my code:

from PIL import Image, ImageGrab
from io import BytesIO

i = ImageGrab.grab()
i.resize((1280, 720))
output = BytesIO()
i.save(output, format = "JPEG")
output.flush()
print(isinstance(Image.open(output), Image.Image))

And the stack trace of the error it throws:

Traceback (most recent call last):
  File "C:/Users/Natecat/PycharmProjects/Python/test.py", line 9, in <module>
    print(isinstance(Image.open(output), Image.Image))
  File "C:\Python27\lib\site-packages\PIL\Image.py", line 2126, in open
    % (filename if filename else fp))
IOError: cannot identify image file <_io.BytesIO object at 0x02394DB0>

I am using the Pillow implementation of PIL.

Natecat
  • 2,175
  • 1
  • 17
  • 20

1 Answers1

46

Think of BytesIO as a file object, after you finish writing the image, the file's cursor is at the end of the file, so when Image.open() tries to call output.read(), it immediately gets an EOF.

You need to add a output.seek(0) before passing output to Image.open().

Lie Ryan
  • 62,238
  • 13
  • 100
  • 144
  • 5
    For anyone stumbling onto this answer, it looks like this may have been resolved in a recent version of BytesIO. I am running Image.open(io.BytesIO(image_contents)) without calling seek(0) with no problems. I had a similar error but it was because the image_contents was not valid image data. – pythonjsgeo Feb 19 '21 at 03:13
  • 6
    No, it's not "fixed in BytesIO". BytesIO is working as designed. Newer versions of `PIL.open()` just called `.seek(0)` unconditionally ([src](https://github.com/python-pillow/Pillow/commit/735d34260814f9180b773723fd741a7da73047ed)) to support reading from HTTP requests, which looks like it unintentionally fixes this issue. What PIL does here by forcing `.seek(0)` breaks the use cases for users that wants to read from container/concatenated archives without decompressing or making additional copies. I guess they probably consider that use case rather niche compared to HTTP request objects. – Lie Ryan Feb 19 '21 at 05:11