将PILLOW图像转换为StringIO

9 投票
1 回答
8576 浏览
提问于 2025-04-18 14:30

我正在写一个程序,这个程序可以接收多种常见的图片格式,但我需要把它们都转换成一种统一的格式来处理。其实格式是什么并不重要,主要是要确保所有的图片格式都是一样的。因为我需要转换图片格式,然后继续处理这些图片,所以我不想把它们保存到硬盘上,只想转换后继续使用。下面是我用StringIO尝试的代码:

image = Image.open(cStringIO.StringIO(raw_image)).convert("RGB")
cimage = cStringIO.StringIO() # create a StringIO buffer to receive the converted image
image.save(cimage, format="BMP") # reformat the image into the cimage buffer
cimage = Image.open(cimage)

但是它返回了以下错误:

Traceback (most recent call last):
  File "server.py", line 77, in <module>
    s.listen_forever()
  File "server.py", line 47, in listen_forever
    asdf = self.matcher.get_asdf(data)
  File "/Users/jedestep/dev/hitch-py/hitchhiker/matcher.py", line 26, in get_asdf
    cimage = Image.open(cimage)
  File "/Library/Python/2.7/site-packages/PIL/Image.py", line 2256, in open
    % (filename if filename else fp))
IOError: cannot identify image file <cStringIO.StringO object at 0x10261d810>

我也尝试过用io.BytesIO,结果也是一样。有没有什么建议可以让我更好地解决这个问题呢?

1 个回答

21

有两种类型的 cStringIO.StringIO() 对象,这取决于你是怎么创建这个实例的;一种是只读的,另一种是可写的。这两者不能互换。

当你创建一个空的 cStringIO.StringIO() 对象时,你实际上得到的是 cStringIO.StringO(注意最后的 O),它只能用来输出,也就是只能写数据。

相反,如果你用初始内容来创建一个对象,就会得到 cStringIO.StringI 对象(最后的 I 表示输入),你不能写数据,只能读取。

这只是 特定于 cStringIO 模块的;而 StringIO(纯 Python 模块)没有这个限制。文档中使用了别名 cStringIO.InputTypecStringIO.OutputType 来表示这些,并且有这样的说明:

StringIO 模块的另一个不同之处是,调用 StringIO() 并传入一个字符串参数会创建一个只读对象。与没有字符串参数创建的对象不同,它没有写入的方法。这些对象通常是不可见的。在错误追踪中,它们会显示为 StringIStringO

使用 cStringIO.StringO.getvalue() 可以从输出文件中获取数据:

# replace cStringIO.StringO (output) with cStringIO.StringI (input)
cimage = cStringIO.StringIO(cimage.getvalue())
cimage = Image.open(cimage)

可以使用 io.BytesIO() 作为替代,但在写入后你需要将其重置:

image = Image.open(io.BytesIO(raw_image)).convert("RGB")
cimage = io.BytesIO()
image.save(cimage, format="BMP")
cimage.seek(0)  # rewind to the start
cimage = Image.open(cimage)

撰写回答