115

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

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

4

6 回答 6

220

您可以使用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模块。

于 2009-03-14T17:21:04.113 回答
31

对于 Python3,需要使用 BytesIO:

from io import BytesIO
from PIL import Image, ImageDraw

image = Image.new("RGB", (300, 50))
draw = ImageDraw.Draw(image)
draw.text((0, 0), "This text is drawn on image")

byte_io = BytesIO()

image.save(byte_io, 'PNG')

阅读更多: http: //fadeit.dk/blog/post/python3-flask-pil-in-memory-image

于 2015-04-30T15:16:32.053 回答
25

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

Imaging/PIL/Image.pyc line 1423 -> raise KeyError(ext) # unknown extension

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

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

import StringIO
output = StringIO.StringIO()
format = 'PNG' # or 'JPEG' or whatever you want
image.save(output, format)
contents = output.getvalue()
output.close()
于 2011-03-31T17:46:26.717 回答
15

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

buf = StringIO.StringIO()
im.save(buf, format='JPEG')
jpeg = buf.getvalue()
于 2009-03-14T17:39:25.690 回答
13

使用现代(截至 2017 年中期 Python 3.5 和 Pillow 4.0):

StringIO 似乎不再像以前那样工作了。BytesIO 类是处理这个问题的正确方法。Pillow 的保存函数需要一个字符串作为第一个参数,但令人惊讶的是,它并没有看到 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')
于 2017-08-23T00:10:07.030 回答
9

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

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

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

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

im.tostring() => 字符串

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

Image.fromstring(mode, size, data) => image

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

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

于 2009-03-14T17:36:43.403 回答