Как отобразить объект изображения PIL в шаблоне?

Если пользователь загружает изображение, и я изменяю его размер с помощью PIL, я получаю объект изображения PIL.

Как отобразить файл PIL Image в шаблоне, прежде чем он будет сохранен в базе данных? Может ли он быть передан как изображение и визуализирован?

Ответы

Ответ 1

Для ограниченного набора браузеров вы можете кодировать изображение base64 и использовать встроенные изображения. См. Вложение изображений Base64.

Решение, которое работает для всех браузеров, представляет собой тег изображения, ссылающийся на представление которое возвращает изображение.

[обновление]

Все, что я хочу, это предоставить пользователю исходное изображение, а затем запросить другую форму для ввода заголовка для изображения (с измененным изображением слева от поля надписи). Затем, когда пользователь нажимает "отправить" изображение, а подпись будет сохранена в экземпляре модели.

Ну... Когда вы используете <img src="foo">, foo всегда извлекается GET, возможно, поэтому он не работает - request.FILES не будет доступен в запросе GET. Если вы откроете Firebug или панель инструментов отладки хрома, на вкладке "Сеть" вы увидите запрос POST с загруженным изображением и после этого получите запрос GET для извлечения изображения.

Вам нужно сохранить изображение где-то между обоими шагами.

как еще я могу его сохранить? Я хотел бы, чтобы это было временным. Считаете ли вы, что это действительно простой способ сделать это, или я должен изучить эти варианты?

Популярные выборы redis и memcached. Вы можете думать о них как о гигантском общем питоне-питоне с датой истечения срока действия. Если изображения маленькие, например аватар, вы также можете сохранить данные изображения в переменной сеанса.

Ответ 2

Да и нет.

Да, вы можете поместить изображения как необработанные данные Base64. Здесь немного script вы можете использовать для тестирования:

import Image
import base64
import StringIO
output = StringIO.StringIO()
im = Image.open("test.png") # Your image here!
im.save(output, format='PNG')
output.seek(0)
output_s = output.read()
b64 = base64.b64encode(output_s)
open("test.html","w+").write('<img src="data:image/png;base64,{0}"/>'.format(b64))

Однако это действительно плохая идея. С несколькими эскизами ваша единственная страница HTML может быть 10 МБ +.

То, что вам действительно нужно делать, - это использовать отдельное представление Django для возврата изображений из объектов PIL в виде файлов PNG, а затем ссылки на это представление в атрибутах img href на вашей странице.

Ответ 3

Вы можете вставлять изображения с кодировкой base64 в тег. Таким образом, вы можете преобразовать изображение PIL в base64, а затем отобразить его.

from PIL import Image
import StringIO

x = Image.new('RGB',(400,400))
output = StringIO.StringIO()
x.save(output, "PNG")
contents = output.getvalue().encode("base64")
output.close()
contents = contents.split('\n')[0]

Затем покажите с помощью:

 <img src="data:image/png;base64,' + contents + ' />

Посмотрите на примерный вывод.