Serve a dynamically generated image with Django
Question:
How do I serve a dynamically generated image in Django?
I have an html tag
<html>
...
<img src="images/dynamic_chart.png" />
...
</html>
linked up to this request handler, which creates an in-memory image
def chart(request):
img = Image.new("RGB", (300,300), "#FFFFFF")
data = [(i,randint(100,200)) for i in range(0,300,10)]
draw = ImageDraw.Draw(img)
draw.polygon(data, fill="#000000")
# now what?
return HttpResponse(output)
I also plan to change the requests to AJAX, and add some sort of caching mechanism, but my understanding is that wouldn’t affect this part of the solution.
Answers:
I’m relatively new to Django myself. I haven’t been able to find anything in Django itself, but I have stumbled upon a project on Google Code that may be of some help to you:
I assume you’re using PIL (Python Imaging Library). You need to replace your last line with (for example, if you want to serve a PNG image):
response = HttpResponse(mimetype="image/png")
img.save(response, "PNG")
return response
See here for more information.
I was looking for a solution of the same problem
And for me this simple approach worked fine:
from django.http import FileResponse
def dyn_view(request):
response = FileResponse(open("image.png","rb"))
return response
Another way is to use BytesIO. BytesIO is like a buffer. So one can save the image (which is fast enough than writing to disk) in that buffer.
from PIL import Image, ImageDraw
import io
def chart(request):
img = Image.new('RGB', (240, 240), color=(250,160,170))
draw = ImageDraw.Draw(img)
draw.text((20, 40), 'some_text')
buff = io.BytesIO()
img.save(buff, 'jpeg')
return HttpResponse(buff.getvalue(), content_type='image/jpeg')
How do I serve a dynamically generated image in Django?
I have an html tag
<html>
...
<img src="images/dynamic_chart.png" />
...
</html>
linked up to this request handler, which creates an in-memory image
def chart(request):
img = Image.new("RGB", (300,300), "#FFFFFF")
data = [(i,randint(100,200)) for i in range(0,300,10)]
draw = ImageDraw.Draw(img)
draw.polygon(data, fill="#000000")
# now what?
return HttpResponse(output)
I also plan to change the requests to AJAX, and add some sort of caching mechanism, but my understanding is that wouldn’t affect this part of the solution.
I’m relatively new to Django myself. I haven’t been able to find anything in Django itself, but I have stumbled upon a project on Google Code that may be of some help to you:
I assume you’re using PIL (Python Imaging Library). You need to replace your last line with (for example, if you want to serve a PNG image):
response = HttpResponse(mimetype="image/png")
img.save(response, "PNG")
return response
See here for more information.
I was looking for a solution of the same problem
And for me this simple approach worked fine:
from django.http import FileResponse
def dyn_view(request):
response = FileResponse(open("image.png","rb"))
return response
Another way is to use BytesIO. BytesIO is like a buffer. So one can save the image (which is fast enough than writing to disk) in that buffer.
from PIL import Image, ImageDraw
import io
def chart(request):
img = Image.new('RGB', (240, 240), color=(250,160,170))
draw = ImageDraw.Draw(img)
draw.text((20, 40), 'some_text')
buff = io.BytesIO()
img.save(buff, 'jpeg')
return HttpResponse(buff.getvalue(), content_type='image/jpeg')