我正在开发一个Flask应用程序,它会生成一个动态图并通过jinja模板显示它。我想使用模板在Flask应用程序中调用一个返回png数据的函数,然后将响应嵌入到数据uri中。
This gist非常接近我的目标,除了我想避免使用url_for
(以及路由)。相反,我想使用数据uri(img src="data:image/png;base64,...
)
答案 0 :(得分:10)
取代将输出作为带有响应的图像发回,取出输出并将其编码为base64:
try: # Python 3
from urllib.parse import quote
except ImportError: # Python 2
from urllib import quote
from base64 import b64encode
from io import BytesIO
png_output = BytesIO()
canvas.print_png(png_output)
data = b64encode(png_output.getvalue()).decode('ascii')
data_url = 'data:image/png;base64,{}'.format(quote(data))
这会将画布写入内存文件,然后将生成的PNG数据编码为base64并在数据URL中进行插值。
答案 1 :(得分:7)
基于您的示例,经过测试和运作的完整解决方案:
from flask import Flask, render_template
import urllib
app = Flask(__name__)
@app.route("/simple.png")
def simple():
import datetime
import StringIO
import random
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.dates import DateFormatter
fig=Figure()
ax=fig.add_subplot(111)
x=[]
y=[]
now=datetime.datetime.now()
delta=datetime.timedelta(days=1)
for i in range(10):
x.append(now)
now+=delta
y.append(random.randint(0, 1000))
ax.plot_date(x, y, '-')
ax.xaxis.set_major_formatter(DateFormatter('%Y-%m-%d'))
fig.autofmt_xdate()
canvas=FigureCanvas(fig)
png_output = StringIO.StringIO()
canvas.print_png(png_output)
png_output = png_output.getvalue().encode("base64")
return render_template("test.html", img_data=urllib.quote(png_output.rstrip('\n')))
if __name__ == "__main__":
app.run()
模板:
<img src="data:image/png;base64,{{img_data}}"/>