Python PIL:如何将PNG图像写入字符串

max*_*axp 91 python python-imaging-library

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

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

sth*_*sth 182

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

import io

with io.BytesIO() as output:
    image.save(output, format="GIF")
    contents = output.getvalue()
Run Code Online (Sandbox Code Playgroud)

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

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

在引入io模块之前的旧Python 2版本中,您将使用该StringIO模块.

  • @Radian,关于save()方法的PIL文档说:`你可以使用文件对象而不是文件名.在这种情况下,您必须始终指定格式.因此,如果第一个参数是文件对象,则必须传入第二个参数,即格式(例如"PNG"). (6认同)
  • 你可以更好地使用`image.save(output,format = image.format)` (4认同)
  • 对我不起作用:(我在Imaging/PIL/Image.pyc第1423行中得到了这个KeyError - >引发KeyError(ext)#未知扩展名 (2认同)

ozo*_*ner 28

对于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')
Run Code Online (Sandbox Code Playgroud)

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


Rad*_*ian 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()
Run Code Online (Sandbox Code Playgroud)


bob*_*nce 13

save()可以获取类似文件的对象以及路径,因此您可以像StringIO一样使用内存缓冲区:

buf= StringIO.StringIO()
im.save(buf, format= 'JPEG')
jpeg= buf.getvalue()
Run Code Online (Sandbox Code Playgroud)


mig*_*ile 12

随着现代(截至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')
Run Code Online (Sandbox Code Playgroud)

  • image_data = faux_file.getvalue()的目的是什么? (2认同)

S.L*_*ott 9

当你说"我希望将这些图像的数量存储在字典中"时,目前尚不清楚这是否是内存中的结构.

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

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

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

im.tostring()=> string

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

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

使用标准的"原始"解码器从字符串中的像素数据创建图像存储器.

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

  • 听起来他想要保留PNG格式,而不是将其缩小为原始像素数据. (2认同)