问题:如何使用PIL将PNG图片写入字符串?
我已经使用PIL生成了图像。如何将其保存到内存中的字符串中?该Image.save()
方法需要一个文件。
我想将几个这样的图像存储在字典中。
I have generated an image using PIL. How can I save it to a string in memory?
The Image.save()
method requires a file.
I’d like to have several such images stored in dictionary.
回答 0
您可以使用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
模块。
You can use the BytesIO
class to get a wrapper around strings that behaves like a file. The BytesIO
object provides the same interface as a file, but saves the contents just in memory:
import io
with io.BytesIO() as output:
image.save(output, format="GIF")
contents = output.getvalue()
You have to explicitly specify the output format with the format
parameter, otherwise PIL will raise an error when trying to automatically detect it.
If you loaded the image from a file it has a format
parameter that contains the original file format, so in this case you can use format=image.format
.
In old Python 2 versions before introduction of the io
module you would have used the StringIO
module instead.
回答 1
对于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
For Python3 it is required to use 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')
Read more: http://fadeit.dk/blog/post/python3-flask-pil-in-memory-image
回答 2
某物的解决方案对我不起作用,
因为在…
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()
sth’s solution didn’t work for me
because in …
Imaging/PIL/Image.pyc line 1423 ->
raise KeyError(ext) # unknown
extension
It was trying to detect the format from the extension in the filename , which doesn’t exist in StringIO case
You can bypass the format detection by setting the format yourself in a parameter
import StringIO
output = StringIO.StringIO()
format = 'PNG' # or 'JPEG' or whatever you want
image.save(output, format)
contents = output.getvalue()
output.close()
回答 3
save()
可以采用类似文件的对象以及路径,因此您可以使用内存缓冲区,例如StringIO
:
buf = StringIO.StringIO()
im.save(buf, format='JPEG')
jpeg = buf.getvalue()
save()
can take a file-like object as well as a path, so you can use an in-memory buffer like a StringIO
:
buf = StringIO.StringIO()
im.save(buf, format='JPEG')
jpeg = buf.getvalue()
回答 4
使用最新版本(自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')
With modern (as of mid-2017 Python 3.5 and Pillow 4.0):
StringIO no longer seems to work as it used to. The BytesIO class is the proper way to handle this. Pillow’s save function expects a string as the first argument, and surprisingly doesn’t see StringIO as such. The following is similar to older StringIO solutions, but with BytesIO in its place.
from io import BytesIO
from PIL import Image
image = Image.open("a_file.png")
faux_file = BytesIO()
image.save(faux_file, 'png')
回答 5
当您说“我希望在字典中存储此类图像的数量”时,尚不清楚这是否是内存结构。
您无需执行任何操作即可将图像存储在内存中。只需将image
对象保留在字典中即可。
如果要将字典写入文件,则可能需要查看 im.tostring()
方法和Image.fromstring()
函数
http://effbot.org/imagingbook/image.htm
im.tostring()=>字符串
使用标准的“原始”编码器返回包含像素数据的字符串。
Image.fromstring(模式,大小,数据)=>图片
使用标准的“原始”解码器根据字符串中的像素数据创建图像存储器。
仅当交换文件时,“格式”(.jpeg,.png等)才在磁盘上起作用。如果您不交换文件,则格式无关紧要。
When you say “I’d like to have number of such images stored in dictionary”, it’s not clear if this is an in-memory structure or not.
You don’t need to do any of this to meek an image in memory. Just keep the image
object in your dictionary.
If you’re going to write your dictionary to a file, you might want to look at im.tostring()
method and the Image.fromstring()
function
http://effbot.org/imagingbook/image.htm
im.tostring() => string
Returns a string containing pixel
data, using the standard “raw”
encoder.
Image.fromstring(mode, size, data) =>
image
Creates an image memory from pixel
data in a string, using the standard
“raw” decoder.
The “format” (.jpeg, .png, etc.) only matters on disk when you are exchanging the files. If you’re not exchanging files, format doesn’t matter.