generate image -> embed in flask with a data uri generate image -> embed in flask with a data uri flask flask

generate image -> embed in flask with a data uri


Instead of sending the output back as an image with a response, take the output and encode it to base64:

try:  # Python 3    from urllib.parse import quoteexcept ImportError:  # Python 2    from urllib import quotefrom base64 import b64encodefrom io import BytesIOpng_output = BytesIO()canvas.print_png(png_output)data = b64encode(png_output.getvalue()).decode('ascii')data_url = 'data:image/png;base64,{}'.format(quote(data))

This has the canvas write to an in-memory file, and the resulting PNG data is then encoded to base64 and interpolated in a data URL.


Complete solution based on your example, tested and working:

from flask import Flask, render_templateimport urllibapp = 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()

Template:

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