PIL的open()方法无法与BytesIO一起使用

31

由于某些原因,当我尝试从一个BytesIO流创建一张图片时,无法识别该图片。以下是我的代码:

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))

并且它抛出的错误堆栈跟踪:

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>

我正在使用Pillow实现的PIL。


你不需要使用 output.flush()。 - iMath
1个回答

46

将BytesIO视为文件对象,当您完成图像写入后,该文件的光标位于文件末尾,因此当Image.open()尝试调用output.read()时,它会立即收到EOF。

在将output传递给Image.open()之前,需要添加output.seek(0)


5
对于无意中看到这个答案的任何人,看起来这个问题可能已经在BytesIO的最新版本中解决了。我正在运行Image.open(io.BytesIO(image_contents)),没有调用seek(0)也没有出现问题。我曾遇到过类似的错误,但那是因为image_contents不是有效的图像数据。 - pythonjsgeo
6
不是"在BytesIO中修复了"。 BytesIO正在按设计工作。新版本的PIL.open()无条件地调用.seek(0)src)以支持从HTTP请求中读取,这似乎意外地解决了此问题。 PIL在这里通过强制执行.seek(0)来破坏了用户想要从容器/串联档案中读取而不进行解压缩或制作其他副本的用例。 我猜他们可能认为与HTTP请求对象相比,这种用例相当小众。 - Lie Ryan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接