Python 如何使用CherryPy在HTTP响应中返回图像
我有生成CairoPython 如何使用CherryPy在HTTP响应中返回图像,python,http,cherrypy,cairo,Python,Http,Cherrypy,Cairo,我有生成CairoImageSurface的代码,我将其公开如下: def preview(...): surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) ... cherrypy.response.headers['Content-Type'] = "image/png" return surface.get_data() preview.exposed = True 这不起作用(浏
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')
的工作原理,但我不确定要将数据转储到什么位置才能返回它。我猜是某个类似文件的对象?根据,get_data()
返回一个缓冲区。我现在也尝试过:
tempf = os.tmpfile()
surface.write_to_png(tempf)
return tempf
另外,创建这个映像并将其保存在内存中(就像我正在尝试的那样)还是将其作为临时文件写入磁盘并从那里提供服务更好?我只需要一次图像,然后它可以被丢弃 您是否尝试过返回str(surface.get_data())?尝试这种“内存中的文件”方法
return StringIO.StringIO(surface.get_data())
添加以下导入:
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"'
另外,创建和保存是否更好
记忆中的这个图像(就像我正在尝试的一样
或将其作为临时文件写入磁盘
从那里归档并送达?我只是
需要图像一次,就可以了
丢弃
如果您只想将此文件提供给浏览器,则没有理由在服务器上的磁盘上创建它。恰恰相反-请记住,访问硬盘会带来性能损失。您之所以失败,是因为不了解
surface.get_data()
的工作原理。
您正试图返回mime类型image/png
但surface.get_data()
返回
普通位图图像(不是带标题的Windows位图文件.BMP),它
是来自“虚拟屏幕”(表面)的普通图像转储
像这样:
0000010000
0000101000
0001000100
0010000010
0001000100
0000101000
0000010000
0000010000
0000101000
0001000100
0010000010
0001000100
0000101000
0000010000
写到png流怎么样?pycairo似乎没有公开该方法。。。很好!对于赏金,你能解释一下为什么吗?回答得很好,zifot-我认为关键是使用“write_to_png”将原始数据转换为png格式。仅仅使用surface.get_data()是行不通的,因为它在内部没有存储为PNG数据(它是ARGB_32)。@Marc Novakowski-谢谢。没错,ImageSurface在内存中以此处描述的格式之一保存数据:。输出文件的格式是不同的。@colinmarc-AFAIK如果你的问题有悬赏,那么在创建悬赏后的两天内,奖励和接受答案(现在是单独的行动)都是可能的。非常感谢,我真的在那里呆了一段时间。=)