Return a Dynamic png from Pylons
Question: What I'm trying to do is have my Pylons app dynamically generate an image
based on some data, and return it in such a way that it can be viewed in a
browser.

So far I am generating my image like this:

    
    
    import Image, ImageDraw
    image = Image.new("RGB", (width, height),"black")
    img_out = ImageDraw.Draw(image)
    img_out.polygon(...
    img_out.text(...
    #etc
    

The image is successfully generated, and can even be saved to file like this:

    
    
    img_out.save(filepath)
    

My problem is that I am not trying to write it to disk, but rather return it
via a Pylons response. Based off of the answers to [another
question](http://stackoverflow.com/questions/2413707/stream-a-file-to-the-
http-response-in-pylons) I was able to get this far:

    
    
    import FileApp
    my_headers = [('Content-Disposition', 'attachment; filename=\"' + user_filename + '\"'), ('Content-Type', 'text/plain')]
    file_app = FileApp(filepath, headers=my_headers)
    return file_app(request.environ, self.start_reponse)
    

Using this solution I can take a png I have saved on the server side and
return it to the user for download. Still, there are two problems here. The
first is that I am forced to write the file to disk and then serve it from
disk, rather than simply using the image straight from code. The second is
that it is actually returning the file, therefore a user is forced to download
it rather than viewing it in their browser.

What I want is for the user to be able to view the file in their browser, not
download it themselves. IDEALLY I wouldn't have to save the image to disk on
the server side either, but I realize it is likely impossible to serve it
without it living on either the server or client's computer.

So my question is this. Can I serve the image straight from code such that the
user will simply see the image in their browser as the response to their
request? If not, can I save the image to disk server side and serve it from
there such that the user will see the image in their browser and not be
prompted to download a file?

(For what it's worth I am using Python 2.6.2 and PasteScript 1.7.4.2)


Answer: Browsers can accept raw data as part of the `src` attribute for `img`'s base64
encoded...

    
    
    from PIL import Image
    from cStringIO import StringIO
    
    a = Image.new('RGB', (10, 10), 'black')
    # ...
    buf = StringIO()
    a.save(buf, 'png')
    b64img = '<img src="data:image/png;base64,{0}" />'.format(buf.getvalue().encode('base64'))
    

So what you do here is build your image, save it into a string buffer in
memory (instead of on disk), then encode it to base64... You return the
`<img>` tag as part of the page (or purely by itself if being lazy) using
whatever templates/etc... Maybe just a `return Response(b64img)` would do
it...

