Dynamic images are often used in web apps, for example to create charts from database data. You create your image in a function and then return the content of the image, with the appropriate response headers.
In many frameworks, you must create a method, bind it to an URL and include this URL in the src property of an img tag. In Nagare you directly associate the method to the img tag.
In this example I've taken the Nagare logo and wrote the current timestamp on it using PIL.
Here's the class definition:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
import cStringIO import time import pkg_resources from PIL import Image, ImageDraw from nagare import presentation class MyApp(object): def get_image(self, h): """Returns the modified Nagare logo In: - ``h`` -- the renderer (not used) """ # Get the Nagare logo requirement = pkg_resources.Requirement.parse('nagare') img = pkg_resources.resource_stream(requirement, '/static/img/logo.gif') # Open the image im = Image.open(img) draw = ImageDraw.Draw(im) # Draw timestamp on it draw.text((15, 10), time.asctime(), fill=0xffffff) # Save it into a StringIO and return the content imgdata = cStringIO.StringIO() im.save(imgdata, 'PNG') return imgdata.getvalue()
Nothing special here. The interesting part is the rendering method for this component:
1 2 3
@presentation.render_for(MyApp) def render(self, h, *args): return h.img.action(self.get_image)
You may have already used the action() method on HTML tags such as a or input. The img tags also have one.
All you have to do is to give to action() a callback, that will take a renderer as argument and will have to return the image data. So I passed to action() the get_image() method of MyApp class. As the function returns the image stream, without explicitly setting the content-type of the HTTP response, Nagare auto discovers the content type and set it by itself.