Python PIL: jak napisać obraz PNG do string

Wygenerowałem obraz za pomocą PIL . Jak Mogę zapisać go do łańcucha w pamięci? Metoda Image.save() wymaga pliku.

Chciałbym mieć kilka takich obrazów zapisanych w słowniku.
Author: Seth Johnson, 2009-03-14

6 answers

Możesz użyć BytesIO Klasa, aby uzyskać owijkę wokół ciągów, które zachowują się jak plik. Obiekt BytesIO zapewnia ten sam interfejs co plik, ale zapisuje zawartość Tylko w pamięci:

import io

with io.BytesIO() as output:
    image.save(output)
    contents = output.getvalue()

Może to prowadzić do KeyError, Jeśli PIL spróbuje automatycznie wykryć format wyjściowy. Aby uniknąć tego problemu, możesz podać format ręcznie:

image.save(output, format="GIF")

W starych wersjach Pythona 2 przed wprowadzeniem modułu io można by użyć StringIO Moduł zamiast tego.

 159
Author: sth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-30 14:50:33

Dla Python3 wymagane jest użycie Bajtesio:

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')

Czytaj więcej: http://fadeit.dk/blog/post/python3-flask-pil-in-memory-image

 25
Author: ozooner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-30 14:41:20

Rozwiązanie Sth nie zadziałało dla mnie
bo w..

Imaging / Pil / Image.linia pyc 1423 -> raise KeyError (ext) # unknown rozszerzenie

Próbował wykryć format z rozszerzenia w nazwie pliku, który nie istnieje w przypadku stringio

Możesz ominąć wykrywanie formatu, ustawiając sam format w parametrze

import StringIO
output = StringIO.StringIO()
format = 'PNG' # or 'JPEG' or whatever you want
image.save(output, format)
contents = output.getvalue()
output.close()
 23
Author: Radian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-31 17:46:26

Save () może przyjmować obiekt podobny do pliku, jak również ścieżkę, więc możesz użyć bufora w pamięci, takiego jak StringIO:

buf= StringIO.StringIO()
im.save(buf, format= 'JPEG')
jpeg= buf.getvalue()
 11
Author: bobince,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-14 17:39:25

Kiedy mówisz "chciałbym mieć liczbę takich obrazów przechowywanych w słowniku", nie jest jasne, czy jest to struktura w pamięci, czy nie.

Nie musisz tego robić, żeby wyciszyć obraz w pamięci. Po prostu zachowaj obiekt image w swoim słowniku.

Jeśli zamierzasz zapisać swój słownik do pliku, warto przyjrzeć się metodzie im.tostring() i funkcji Image.fromstring()

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

Im.tostring () = > string

Zwraca łańcuch zawierający piksel danych, stosując standard " raw" enkoder.

Obraz.fromstring (mode, size, data) => obraz

Tworzy pamięć obrazu z piksela danych w ciągu znaków, przy użyciu standardu dekoder "raw".

"format" (.jpeg,png itp.) ma znaczenie tylko na dysku podczas wymiany plików. Jeśli nie wymieniasz plików, format nie ma znaczenia.

 8
Author: S.Lott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-11 16:24:40

Z nowoczesnym (od połowy 2017 roku Python 3.5 i Pillow 4.0):

StringIO nie wydaje się już działać tak, jak kiedyś. Klasa BytesIO jest właściwym sposobem radzenia sobie z tym. Funkcja save Pillow oczekuje string jako pierwszego argumentu i zaskakująco nie widzi StringIO jako takiego. Poniżej jest podobny do starszych rozwiązań StringIO, ale z BytesIO w jego miejsce.

from io import BytesIO
from PIL import Image

image = Image.open("a_file.png")
faux_file = BytesIO()
image_data = faux_file.getvalue()
image.save(faux_file, 'png')
 6
Author: mightypile,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-23 00:17:43