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

Was it helpful?

Solution

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top