如何使用PIL将PNG图片写入字符串?


99

我已经使用PIL生成了图像。如何将其保存到内存中的字符串中?该Image.save()方法需要一个文件。

我想将几个这样的图像存储在字典中。

Answers:


194

您可以使用BytesIO该类来获取行为类似于文件的字符串的包装器。该BytesIO对象提供与文件相同的接口,但仅将内容保存在内存中:

import io

with io.BytesIO() as output:
    image.save(output, format="GIF")
    contents = output.getvalue()

您必须使用format参数明确指定输出格式,否则PIL在尝试自动检测到它时会引发错误。

如果从文件加载图像,则图像的format参数包含原始文件格式,因此在这种情况下,您可以使用format=image.format

在引入io模块之前的旧Python 2版本中,您会改用该StringIO模块。


1
是! 这正是我想要的。我用google搜索python,字符串,读取器,写入器,缓冲区的每种组合,但没有提出任何建议。谢谢!
rik.the.vik

2
对我不起作用:(我在Imaging / PIL / Image.pyc第1423行中收到此KeyError->引发KeyError(ext)#未知扩展名
Radian

6
@Radian,save()方法上的PIL文档说:You can use a file object instead of a filename. In this case, you must always specify the format.因此,如果第一个参数是文件对象,则必须传入第二个参数,即格式(例如'PNG')。
Su Zhang

1
在当前的Python版本中,StringIO位于io包中,您必须编写:from io import StringIO
Spoutnik16

4
您可以更好地使用image.save(output, format=image.format)
reetesh11


24

某物的解决方案对我不起作用,
因为在...

Imaging / PIL / Image.pyc第1423行->提高KeyError(ext)#未知扩展名

它试图从文件名的扩展名中检测格式,这在StringIO情况下不存在

您可以通过在参数中自行设置格式来绕过格式检测

import StringIO
output = StringIO.StringIO()
format = 'PNG' # or 'JPEG' or whatever you want
image.save(output, format)
contents = output.getvalue()
output.close()

14

save()可以采用类似文件的对象以及路径,因此您可以使用内存缓冲区,例如StringIO

buf = StringIO.StringIO()
im.save(buf, format='JPEG')
jpeg = buf.getvalue()

谢谢。StringIO-那就是我需要的。
maxp

在获取PNG,JPEG或实际文件格式时,save()接口比tostring()接口干净得多。
Kekoa 2010年

13

使用最新版本(自2017年中开始,Python 3.5和Pillow 4.0):

StringIO似乎不再像以前那样工作。BytesIO类是处理此问题的正确方法。Pillow的save函数期望将字符串作为第一个参数,并且令人惊讶地没有这样的StringIO。以下内容与较早的StringIO解决方案相似,但是使用了BytesIO。

from io import BytesIO
from PIL import Image

image = Image.open("a_file.png")
faux_file = BytesIO()
image.save(faux_file, 'png')

2
image_data = faux_file.getvalue()的目的是什么?
瑞安

@Ryan很好,根本没有目的。它是从测试中遗留下来的,最后被删除了。
强大的

9

当您说“我希望在字典中存储此类图像的数量”时,尚不清楚这是否是内存结构。

您无需执行任何操作即可将图像存储在内存中。只需将image对象保留在字典中即可。

如果要将字典写入文件,则可能需要查看 im.tostring()方法和Image.fromstring()函数

http://effbot.org/imagingbook/image.htm

im.tostring()=>字符串

使用标准的“原始”编码器返回包含像素数据的字符串。

Image.fromstring(模式,大小,数据)=>图片

使用标准的“原始”解码器根据字符串中的像素数据创建图像存储器。

仅当交换文件时,“格式”(.jpeg,.png等)才在磁盘上起作用。如果您不交换文件,则格式无关紧要。


2
听起来他想保留PNG格式,而不是将其缩小为原始像素数据。
本·布兰克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.