如何在python中从字符串创建图像

如何在python中从字符串创建图像,python,string,image,sockets,Python,String,Image,Sockets,我目前在Python程序中从二进制数据字符串创建图像时遇到问题。我通过套接字接收二进制数据,但当我尝试以下方法时: buff = StringIO.StringIO() #buffer where image is stored #Then I concatenate data by doing a buff.write(data) #the data from the socket im = Image.open(buff) 我得到了一个“图像类型无法识别”的例外。我知道我收到的数据是正确

我目前在Python程序中从二进制数据字符串创建图像时遇到问题。我通过套接字接收二进制数据,但当我尝试以下方法时:

buff = StringIO.StringIO() #buffer where image is stored
#Then I concatenate data by doing a 
buff.write(data) #the data from the socket
im = Image.open(buff)
我得到了一个“图像类型无法识别”的例外。我知道我收到的数据是正确的,因为如果我将图像写入文件,然后打开文件,它就会工作:

buff = StringIO.StringIO() #buffer where image is stored
buff.write(data) #data is from the socket
output = open("tmp.jpg", 'wb')
output.write(buff)
output.close()
im = Image.open("tmp.jpg")
im.show()

我想我在使用StringIO类时可能做错了什么,但我不确定

我怀疑在将StringIO对象传递给PIL之前,您没有返回到缓冲区的开头。下面的一些代码演示了问题和解决方案:

>>> buff = StringIO.StringIO()
>>> buff.write(open('map.png', 'rb').read())
>>> 
>>> #seek back to the beginning so the whole thing will be read by PIL
>>> buff.seek(0)
>>>
>>> Image.open(buff)
<PngImagePlugin.PngImageFile instance at 0x00BD7DC8>
>>> 
>>> #that worked.. but if we try again:
>>> Image.open(buff)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\python25\lib\site-packages\pil-1.1.6-py2.5-win32.egg\Image.py", line 1916, in open
    raise IOError("cannot identify image file")
IOError: cannot identify image file
buff=StringIO.StringIO() >>>buff.write(打开('map.png','rb').read()) >>> >>>#回到开头,让PIL阅读整件事 >>>buff.seek(0) >>> >>>图像。打开(buff) >>> >>>#奏效了。。但如果我们再试一次: >>>图像。打开(buff) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 打开文件“c:\python25\lib\site packages\pil-1.1.6-py2.5-win32.egg\Image.py”,第1916行 raise IOError(“无法识别图像文件”) IOError:无法识别图像文件
确保在读取任何StringIO对象之前调用buff.seek(0)。否则,您将从缓冲区的末尾读取数据,这看起来像一个空文件,很可能会导致您看到的错误。

您可以调用buff.seek(0),或者,更好的做法是,使用数据初始化内存缓冲区
StringIO.StringIO(数据)

明天我将尝试一下!谢谢你的意见和建议。StringIO模块没有很好的文档记录(至少我可以找到),您可以改为执行
buff=StringIO.StringIO(open('map.png','rb').read())
。不再需要
seek()
。作为对您关于StringIO被记录的评论的回复:StringIO的想法是它只是一个内存中的文件。如果调用file.write(“…”),然后调用file.read(),而不返回到开头,则在普通磁盘文件上的行为将是相同的。试试看:)