如何通过 render_template 将渲染图传递给 html 文件?

Posted

技术标签:

【中文标题】如何通过 render_template 将渲染图传递给 html 文件?【英文标题】:How to pass rendered plot to a html file through render_template? 【发布时间】:2019-05-14 23:38:38 【问题描述】:

我正在关注这个answer,我想使用 render_template 来调用我的 html 文件,而不是直接在我的 py 中运行 plot。

我想使用类似的东西:

return render_template('hello.html', plot_url)

代替:

return '<img src="data:image/png;base64,">'.format(plot_url)

我的问题是,是否有任何方法可以将绘图传递给 html 文件,然后在烧瓶中运行?

编辑:

@app.route('/')
def build_Plot():
    y = [1, 2, 3, 4, 5]
    x = [0, 2, 1, 3, 4]
    plt.plot(x, y)
    output = io.BytesIO()
    plt.savefig(output, format='png')
    output.seek(0)
    plot_data = base64.b64encode(output.getvalue()).decode()
    return render_template("home.html", url=plot_data)

在 home.html 中:

<!doctype html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>MyFlaskApp</title>
    </head>
    <body>
        % block body %
            <img src="data:image/png;base64 =  url  "/>
        % endblock %
    </body>
</html>

【问题讨论】:

【参考方案1】:

首先,要足够注意你的html文件名,我看到两个不同的名字,hello.htmlhome.html。然后尝试使用matplotlib.backends.backend_agg如下:

from base64 import b64encode
from io import BytesIO
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
@app.route('/')
def build_Plot():
    output = io.BytesIO()
    y = [1, 2, 3, 4, 5]
    x = [0, 2, 1, 3, 4]
    plt.plot(x, y)
    f = plt.figure()
    canvas = FigureCanvas(f)
    canvas.print_png(output)
    plot_data= b64encode(output.getvalue()).decode('ascii')
    output.seek(0)
    return render_template("home.html", url=plot_data)

通过这种方式,它让画布写入内存文件,然后将生成的 PNG 数据编码为 base64 并插入数据 URL。

【讨论】:

成功了!我做了一些改变,现在按预期工作。非常感谢你【参考方案2】:

plot_url 实际上存储的是图像的 URL。所以如果你已经有一个像 hello.html 这样的 HTML 页面,你可以在渲染它的时候这样做:

你好.html:

<!doctype html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>MyFlaskApp</title>
    </head>
    <body>
        % block body %
            % if plot %
                <img src="data:image/png;base64,url">
            % endif %
        % endblock %
    </body>
</html>

在 Python 文件中,您可以执行以下操作:

return render_template("hello.html",plot=True, url=plot_url) 

注意 plot_url 来自您链接的答案中提到的base64.b64encode(img.getvalue()).decode() 行。

【讨论】:

不起作用。当我使用我的解决方案运行页面时,它可以工作,但是使用您的解决方案不会在本地主机页面中加载任何绘图 刚刚改了,可以试试吗?在 url 周围添加了一对额外的大括号。 给我错误:jinja2.exceptions.TemplateSyntaxError: expected token ':', got '' 请进行最新编辑,对于这个愚蠢的错误,我深表歉意。 不幸的是没有再次加载情节【参考方案3】:

假设您的意思是将图像与页面一起传递(而不是在 img 标记中包含 URL,数据 URL 的格式表明您需要

<img src="data:image/png;base64, data " />

其中data 是图像的 PNG 表示的 base64 编码。

但如果你的意思是传递一个 URL,那么你会想要类似的东西

<img src=" url " />

其中url 是指向应用中视图方法的链接,该方法将返回非base64 编码的图像。

【讨论】:

我尝试了您的解决方案,但得到了回应:127.0.0.1 - - [13/Dec/2018 23:40:03] "GET /iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCA.......hAAAAAy/w/ eHm5zQpnsLwAAAAASUVORK5CYII= HTTP/1.1" 404 - 对于第二个,它只是得到一个长刺,而不是像 223 或 404 这样的数字......并且不会在本地页面中加载绘图 我提供了两种解决方案。看起来您尝试将 base64 编码的图像(这是第一个解决方案想要的)传递给第二个。 在我的代码中,plot_url = base64.b64encode(output.getvalue()).decode()type(plot_url)==&lt;type 'unicode'&gt; 。不知道我该怎么办!!我正在使用 plot_url 这种格式,因为我想要一个动态图。 那么,假设output.getvalue() 真的是一个PNG,&lt;img src="data:image/png;base64, plot_url " /&gt; 就是你想要的,虽然plot_url 这个名字有误导性。真的是plot_data。如果这不起作用,您需要向我们展示通往output 的代码。

以上是关于如何通过 render_template 将渲染图传递给 html 文件?的主要内容,如果未能解决你的问题,请参考以下文章

Flask 渲染跨服务器的html模板

flask模板

如何使 R 渲染图更快

编程学习之如何在Node.js中优化服务器端渲染?[图]

Airflow Jinja 渲染模板

如何在导出图层之前将1条调整曲线应用于每个图层(渲染为视频)?