如何使用CherryPy返回HTTP响应中的图像

时间:2010-06-17 18:15:33

标签: python http cherrypy cairo

我有生成开罗ImageSurface的代码,我将其暴露出来:

def preview(...):
    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
    ...
    cherrypy.response.headers['Content-Type'] = "image/png"
    return surface.get_data()
preview.exposed = True

这不起作用(浏览器报告图像有错误)。

我已经测试了surface.write_to_png('test.png')的工作原理,但我不确定要将数据转储到哪里以返回它。我猜一些像文件一样的对象?根据{{​​3}},get_data()返回缓冲区。我现在也尝试过:

tempf = os.tmpfile()
surface.write_to_png(tempf)
return tempf

此外,最好是在内存中创建并保存此图像(就像我正在尝试的那样),或者将其作为临时文件写入磁盘并从那里提供服务?我只需要一次图像,然后就可以丢弃了。

4 个答案:

答案 0 :(得分:17)

添加以下导入:

from cherrypy.lib import file_generator
import StringIO

然后像这样:

def index(self):
    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
    cherrypy.response.headers['Content-Type'] = "image/png"

    buffer = StringIO.StringIO()
    surface.write_to_png(buffer)
    buffer.seek(0)

    return file_generator(buffer)

另外,如果您正在提供独立文件(即它不是网页的一部分)并且您不希望将其呈现到浏览器中,而是将其视为要保存在磁盘上的文件,那么您需要一个更多标题:

cherrypy.response.headers['Content-Disposition'] = 'attachment; filename="file.png"'
  

此外,创建和保留更好   这张图片在记忆中(就像我在努力   做)或作为临时写入磁盘   归档并从那里提供服务?我只是   需要图像一次,然后就可以了   丢弃。

如果您要做的唯一事情是将此文件提供给浏览器,则没有理由在服务器上的磁盘上创建它。恰恰相反 - 请记住,访问硬盘会带来性能损失。

答案 1 :(得分:1)

你因为不理解surface.get_data()的工作而失败了。 您正在尝试返回mime-type image/pngsurface.get_data()返回 普通位图图像(不是带有标题的Windows位图文件.BMP) 是来自“虚拟屏幕”(表面)的普通图像转储

像这样:

0000010000
0000101000
0001000100
0010000010
0001000100
0000101000
0000010000

答案 2 :(得分:0)

您是否尝试过return str(surface.get_data())

答案 3 :(得分:0)

尝试使用“内存中的文件”方法

return StringIO.StringIO(surface.get_data())