我有生成开罗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
此外,最好是在内存中创建并保存此图像(就像我正在尝试的那样),或者将其作为临时文件写入磁盘并从那里提供服务?我只需要一次图像,然后就可以丢弃了。
答案 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/png
但surface.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())