我正在编写一个程序,可以接收各种常见图像格式的图像,但需要以一种一致的格式检查它们。什么图像格式并不重要,主要是它们都是相同的。由于我需要转换图像格式,然后继续使用图像,所以我不想将其保存到磁盘;把它转换一下,然后继续。下面是我使用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>
我也试过了。BytesIO得到了相同的结果。对于如何处理这个问题,有什么建议吗?
有两种类型的 cStringIO.StringIO()
对象取决于如何创建实例;一个用来阅读,另一个用来写作。
当你创建一个空 cStringIO.StringIO()
对象时,你真的得到了一个cStringIO.StringO
(注意最后的O
)类,它只能作为输出,即写入
相反,创建一个具有初始内容的对象会产生一个cStringIO.StringI
对象(以I
结尾的输入),您永远不能写入它,只能从它读取。
这是特有的,只是 cStringIO
模块;StringIO
(纯python模块)没有这个限制。文档使用别名cStringIO.InputType
和cStringIO.OutputType
表示它们,并有如下说明:
与
StringIO
模块的另一个区别是,用字符串参数调用StringIO()
创建一个只读对象。与不带字符串参数创建的对象不同,它没有写方法。这些物体通常是不可见的。它们在traceback中显示为StringI
和StringO
。
使用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)