7

我有生成 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')工作原理,但我不确定将数据转储到什么中以返回它。我猜是一些类似文件的对象?根据pycairo 文档get_data()返回一个缓冲区。我现在也尝试过:

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

另外,在内存中创建和保存这个图像(就像我正在尝试做的那样)或者将它作为临时文件写入磁盘并从那里提供它会更好吗?我只需要图像一次,然后可以将其丢弃。

4

4 回答 4

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

另外,在内存中创建和保存这个图像(就像我正在尝试做的那样)或者将它作为临时文件写入磁盘并从那里提供它会更好吗?我只需要图像一次,然后可以将其丢弃。

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

于 2010-06-20T20:26:45.857 回答
1

你失败是因为不了解surface.get_data(). 您正在尝试返回 mime-typeimage/pngsurface.get_data()返回纯位图图像(不是带有标题的 Windows 位图文件 .BMP),它是来自“虚拟屏幕”(表面)的纯图像转储

像这样:

0000010000
0000101000
0001000100
0010000010
0001000100
0000101000
0000010000
于 2011-01-25T07:30:16.977 回答
0

Have you tried return str(surface.get_data())?

于 2010-06-17T22:27:04.630 回答
0

试试这个“内存中的文件”方法

return StringIO.StringIO(surface.get_data())
于 2010-06-18T06:38:18.230 回答