[Django]-How do I display a PIL Image object in a template?

16👍

For a limited set of browsers, you can base64 encode the image and use inline images. See Embedding Base64 Images.

A solution that works for all browsers is an image tag referencing a view that returns the image.

[update]

All I want is for the user to submit the original image, and then be prompted by another form to input a caption for the image (with the resized image to the left of the caption field). Then when the user hits “submit” the image and the caption get saved in a model instance.

Well… When you use <img src="foo">, foo is always retrieved by a GET perhaps that is why it is not working – request.FILES will not be available in a GET request. If you open firebug or the chrome debug toolbar, in the network tab, you will see the POST request with the uploaded image and after that a GET request to fetch the image.

You have to save the image somewhere between both steps.

how else could i save it? I would love for it to be temporary. Do you think there’s a really easy way to do this, or should I go look into those options?

Popular choices are redis and memcached. You can think of them as giant shared python dict with an expire date. If the images are small, like an avatar, you can also save the image data in a session variable.

16👍

Yes and no.

Yes, you can put the images as raw Base64 data. Here’s a little script you can use to test this:

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

However, this is a really bad idea. With multiple thumbnails, your single HTML page might be 10MB+.

What you really should be doing is using a separate Django view to return images from PIL objects as PNG files, and then referencing that view in the img href attributes on your page.

8👍

You can embed base64 encoded images into an tag. So you could convert PIL image to base64 and then display it.

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]

Then show with:

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

Look to an example output.

Leave a comment