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

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

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

3 ответа

Решение

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

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

[Обновить]

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

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

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

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

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

И да и нет.

Да, вы можете поместить изображения в виде необработанных данных Base64. Вот небольшой скрипт, который вы можете использовать для проверки этого:

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, а затем ссылаться на это представление в imghref атрибуты на вашей странице.

Вы можете встраивать изображения в кодировке 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 + ' />

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

Другие вопросы по тегам