Я создал изображение с помощью PIL . Как мне сохранить его в виде строки в памяти? Для Image.save()
метода требуется файл.
Хотелось бы, чтобы в словаре было несколько таких изображений.
Ответы:
Вы можете использовать этот BytesIO
класс, чтобы получить оболочку вокруг строк, которая ведет себя как файл. BytesIO
Объект обеспечивает один и тот же интерфейс , как файл, но сохраняет содержимое только в памяти:
import io
with io.BytesIO() as output:
image.save(output, format="GIF")
contents = output.getvalue()
Вы должны явно указать выходной формат с format
параметром, иначе PIL вызовет ошибку при попытке ее автоматического обнаружения.
Если вы загрузили изображение из файла, у него есть format
параметр, содержащий исходный формат файла, поэтому в этом случае вы можете использовать format=image.format
.
В старых версиях Python 2 до введения io
модуля вы бы использовали его StringIO
вместо него.
You can use a file object instead of a filename. In this case, you must always specify the format.
Итак, если первый аргумент является файловым объектом, вы должны передать второй аргумент, который является форматом (например 'PNG'
).
from io import StringIO
image.save(output, format=image.format)
Для 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
Решение sth не сработало для меня,
потому что в ...
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()
save()
может принимать файловый объект, а также путь, поэтому вы можете использовать буфер в памяти, например StringIO
:
buf = StringIO.StringIO()
im.save(buf, format='JPEG')
jpeg = buf.getvalue()
С современными (по состоянию на середину 2017 года Python 3.5 и Pillow 4.0):
StringIO больше не работает, как раньше. Класс BytesIO - правильный способ справиться с этим. Функция сохранения подушки ожидает строку в качестве первого аргумента и, что удивительно, не видит 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')
Когда вы говорите: «Я бы хотел, чтобы количество таких изображений было сохранено в словаре», неясно, является ли это структурой в памяти или нет.
Вам не нужно делать ничего из этого, чтобы сохранить образ в памяти. Просто сохраните image
объект в своем словаре.
Если вы собираетесь записать свой словарь в файл, вы можете посмотреть im.tostring()
метод и Image.fromstring()
функцию
http://effbot.org/imagingbook/image.htm
im.tostring () => строка
Возвращает строку, содержащую пиксельные данные, с использованием стандартного «сырого» кодировщика.
Image.fromstring (режим, размер, данные) => изображение
Создает память изображения из пиксельных данных в строке с использованием стандартного «сырого» декодера.
«Формат» (.jpeg, .png и т. Д.) Имеет значение только на диске, когда вы обмениваетесь файлами. Если вы не обмениваетесь файлами, формат не имеет значения.