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

col*_*arc 7 python http cherrypy cairo

我有生成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
Run Code Online (Sandbox Code Playgroud)

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

我已经测试了它的surface.write_to_png('test.png')工作原理,但是我不确定将数据转储到什么内容以返回它.我猜一些像文件一样的对象?根据pycairo文档,get_data()返回一个缓冲区.我现在也尝试过:

tempf = os.tmpfile()
surface.write_to_png(tempf)
return tempf
Run Code Online (Sandbox Code Playgroud)

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

zif*_*fot 17

添加这些导入:

from cherrypy.lib import file_generator
import StringIO
Run Code Online (Sandbox Code Playgroud)

然后像这样:

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)
Run Code Online (Sandbox Code Playgroud)

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

cherrypy.response.headers['Content-Disposition'] = 'attachment; filename="file.png"'
Run Code Online (Sandbox Code Playgroud)

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

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