2013-07-21 43 views
1
返回动态PNG

我试图做的是有我的主塔应用程序动态生成基于一些数据的图像,并以这样的方式,它可以在浏览器中查看返回。从主塔

到目前为止我生成我的形象是这样的:

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

的图像被成功生成,甚至可以保存到文件中是这样的:

img_out.save(filepath) 

我的问题是,我不是试图写入磁盘,而是通过Pylons响应返回。根据关答案的another question我能够远远地得到这样的:

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) 

使用该解决方案,我可以拿我已经保存在服务器端的PNG文件并返回给用户下载。但是,这里有两个问题。首先,我被迫将文件写入磁盘,然后从磁盘提供,而不是直接从代码中直接使用该图像。第二个是它实际上是返回文件,因此用户被迫下载它而不是在浏览器中查看它。

我要的是用户是能查看该文件在他们的浏览器,而不是下载它自己。理想情况下,我不必将图像保存到服务器端的磁盘上,但是我发现如果服务器或客户端计算机上没有它,它可能无法提供服务。

所以我的问题是这样的。我是否可以直接从代码提供图像,以便用户只需在浏览器中将图像视为对其请求的回应?如果没有,我可以将图像保存到磁盘服务器端并从那里提供,以便用户可以在浏览器中看到图像,而不会提示下载文件?

(对于什么是值得我用Python 2.6.2和PasteScript 1.7.4.2)

回答

1

浏览器可以接受原始数据编码为img的BASE64的src属性的一部分......

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

所以你在这里做的是建立你的图像,将其保存到内存(而不是磁盘)的字符串缓冲区,然后将其编码为base64 ...您将<img>标记作为页面的一部分返回(或纯粹本身如果是懒惰)使用任何模板/等...也许只是一个return Response(b64img)会做到这一点...

+0

我没意识到你可以用这种方式返回缓冲区。这正是我所期待的,非常感谢。 –