Ben*_* S. 20 python cgi matplotlib
这个问题在这里以类似的方式提出,但答案是我的头脑(我是python和web开发的新手),所以我希望有一个更简单的方法或者可以用不同的方式解释.
我正在尝试使用matplotlib生成一个图像并在没有先将文件写入服务器的情况下提供它.我的代码可能有点傻,但它是这样的:
import cgi
import matplotlib.pyplot as pyplot
import cStringIO #I think I will need this but not sure how to use
...a bunch of matplotlib stuff happens....
pyplot.savefig('test.png')
print "Content-type: text/html\n"
print """<html><body>
...a bunch of text and html here...
<img src="test.png"></img>
...more text and html...
</body></html>
"""
Run Code Online (Sandbox Code Playgroud)
我认为不是做pyplot.savefig('test.png'),而是应该创建一个cstringIO对象,然后执行以下操作:
mybuffer=cStringIO.StringIO()
pyplot.savefig(mybuffer, format="png")
Run Code Online (Sandbox Code Playgroud)
但我很失落.我见过的所有例子(例如http://lost-theory.org/python/dynamicimg.html)都涉及到类似的事情.
print "Content-type: image/png\n"
Run Code Online (Sandbox Code Playgroud)
我不知道如何将它与我已经输出的HTML集成.
Tho*_*anz 19
你应该
因此,如果发生错误savefig,您仍然可以返回其他内容,甚至是另一个标头.之前不会识别某些错误,例如文本的一些问题,图像尺寸太大等.
你需要知道savefig在哪里写输出.你可以做:
format = "png"
sio = cStringIO.StringIO()
pyplot.savefig(sio, format=format)
print "Content-Type: image/%s\n" % format
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) # Needed this on windows, IIS
sys.stdout.write(sio.getvalue())
Run Code Online (Sandbox Code Playgroud)
如果要将图像嵌入HTML:
print "Content-Type: text/html\n"
print """<html><body>
...a bunch of text and html here...
<img src="data:image/png;base64,%s"/>
...more text and html...
</body></html>""" % sio.getvalue().encode("base64").strip()
Run Code Online (Sandbox Code Playgroud)
上面的答案有点过时了 - 这是我在Python3 +上获取图形数据的原始字节的原因.
import matplotlib.pyplot as plt
from io import BytesIO
fig = plt.figure()
plt.plot(range(10))
figdata = BytesIO()
fig.savefig(figdata, format='png')
Run Code Online (Sandbox Code Playgroud)
如其他答案所述,您现在需要将'Content-Type'标题设置为'image/png'并写出字节.
根据您用作网络服务器的内容,代码可能会有所不同.我使用Tornado作为我的网络服务器,这样做的代码是:
self.set_header('Content-Type', 'image/png')
self.write(figdata.getvalue())
Run Code Online (Sandbox Code Playgroud)
我的第一个问题是:图像经常变化吗?你想保留旧的吗?如果它是一个实时的东西,那么你对优化的追求是合理的.否则,动态生成图像的好处并不那么重要.
目前的代码需要2个请求:
可能最简单的方法(将网络请求保持在最低限度)是@Alex L'的评论,它允许您通过构建包含嵌入图像的HTML在单个请求中完成.
你的代码是这样的:
# Build your matplotlib image in a iostring here
# ......
#
# Initialise the base64 string
#
imgStr = "data:image/png;base64,"
imgStr += base64.b64encode(mybuffer)
print "Content-type: text/html\n"
print """<html><body>
# ...a bunch of text and html here...
<img src="%s"></img>
#...more text and html...
</body></html>
""" % imgStr
Run Code Online (Sandbox Code Playgroud)
这段代码可能不会开箱即用,但显示了这个想法.
请注意,这是一般一个坏主意,如果你的形象并没有真正改变过于频繁或产生需要很长的时间,因为它会每次都产生.
另一种方法是生成原始的html.加载它将触发"test.png"的请求.您可以通过已提及的缓冲流式解决方案或静态文件单独提供.
就个人而言,我坚持使用一个解耦的解决方案:通过另一个进程生成图像(确保总有一个图像可用)并使用一个非常轻的东西来生成和提供HTML.
HTH,
小智 5
python3对我有用的是:
buf = io.BytesIO()
plt.savefig(buf, format='png')
image_base64 = base64.b64encode(buf.getvalue()).decode('utf-8').replace('\n', '')
buf.close()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19317 次 |
| 最近记录: |