show image in Flask - python

I am trying to render a image from my sqlite3 database, by using this library:
#!/usr/bin/python3
from flask import Flask, render_template, request, send_file
from flask_sqlalchemy import SQLAlchemy
from io import BytesIO
import base64
#app.route('/show/')
def show():
file_data = FileContents.query.filter_by(id=3).first()
image = b64encode(file_data.data)
return render_template('display.html', image = image)
and putting this variable in the html:
<html>
<body>
<img src="data:image;base64,{{image}}"/>
</body>
</html>
But I can't show the image (I am using python3 and google chorme) can someone help to get it?

You can add the extension. Example: <img src="data:image/png;base64,{{ image }}"\>
And decode image to utf-8 return render_template('display.html', image = image.decode('utf8'))

Related

File reading with Python

I have a system to load image files from html but once I select my file and load it from the front end I need a python api to read that image file I select. How can I connect python to my html?
So, to be specific it would be to load an image file with html and have my python api (I use flask) download it and read it to extract data.enter image description here
The html to load the file would be:
<form action="" method="POST" enctype=multipart/form-data>
<div class="col-md-6">
<input type="file" name="file">
<input class="button button-block button-primary" type="submit" value="Upload">
</div>
</form>
The python API to download and read the file would be:
import os
from flask import Flask, render_template, request
from werkzeug import secure_filename
from PIL import Image
# instance of the Flask object
app = Flask(__name__)
# Carpeta de subida
app.config['UPLOAD_FOLDER'] = './Archivos GTiff'
#app.route("/")
#app.route("imgeo/upload-img.html")
def upload_file():
# render the template "upload-img.html"
return render_template('upload-img.html')
#app.route('imgeo/upload-img.html')
def viewer():
"""Show a map to view the GeoJSON returned from a ImGeo endpoint"""
return render_template('imgeo/upload-img.html')
#app.route("imgeo/upload-img.html", methods=['POST'])
def uploader():
if request.method == 'POST':
# we get the file from the "file" input
f = request.files['archivo']
filename = secure_filename(f.filename)
# Save the file in the directory "tiff files".
f.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
# We return a satisfactory answer
return "<h1>File uploaded successfully</h1>"
if __name__ == '__main__':
# Start the application
app.run(debug=True)
You could try to encode your image in base64 with JavaScript, send the result with a POST request, and then (in Python) decode it. Check out these two threads:
How can I convert an image into Base64 string using JavaScript? (JavaScript)
Convert string in base64 to image and save on filesystem (Python)
Here is a similar question too:
Sending an image from html to python script through CGI

Render graph from Python / Flask to HTML using Jinja2

I have written bunch of code but it is not rendering the chart inside HTML for some reason. Program however runs and creates an image in Static folder. Can someone tell me how I can pass this "image" in Jinja2 in in HTML in order to view it in HTML?
Flask code:
#app.route('/', methods=['GET', 'POST'])
def index():
image = False
from flask import Flask, render_template, request
if request.method == 'POST':
a = int(request.form['a'])
x = np.linspace(-20, 20, 20)
y = a * x
plt.plot(x,y)
plt.savefig('C:/Users/name/PycharmProjects/qtcalc1/static/image.png')
image = url_for('static', filename = image)
print(image)
plt.show()
return render_template('graphtry.html', image = image)
Note view function code is indented well on my end. I need solution for how to render this image in my HTML file graphtry.html using Jinja2. My current HTML code is as follows:
<img src ="{{image}}" >
When you write
image = url_for('static', filename = image)
the value of image variable in the argument is False (from line 3). You have to pass the actual filename, that is in this example: image.png.
image = url_for('static', filename='image.png')
And also, remove the extra space after src attribute:
<img src="{{image}}" />

Generate pdf plot in Flask

I'd like to create a small app in Flask which:
1. Allows the user to upload data, in csv
2. Does stuff to the data (in this example, nothing will be done)
3. Plot results
4. Allow the user to download a plot of the results as pdf.
Code so far:
app.py
from flask import Flask, Response, request, render_template
import matplotlib.pyplot as plt
import matplotlib
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.backends.backend_svg import FigureCanvasSVG
import io
import csv
import pandas as pd
app = Flask(__name__)
#app.route("/", methods=['POST', 'GET'])
def index():
return render_template("index.html")
#app.route('/transform', methods=["GET", "POST"])
def transform_view():
""" process data and render plot on the fly.
"""
# GET input csv
f = request.files['input_file']
if not f:
return "Main input file not found!"
# Read uploaded data as a Stream into a dataframe.
stream = io.StringIO(f.stream.read().decode("UTF8"), newline=None)
csv_input = csv.reader(stream)
contents = []
for row in csv_input:
contents.append(row)
d0 = pd.DataFrame(data=contents[1:], columns=contents[0])
# Change to numeric columns
d0[["col1", "col2"]] = d0[["col1", "col2"]].apply(pd.to_numeric)
# Plot
fig, ax = plt.subplots()
bplot = ax.boxplot([d0["col1"], d0["col2"]])
# Print out plot as pdf?
#output = io.BytesIO()
return render_template("index.html")
if __name__ == "__main__":
app.run(debug=True)
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<form action="/transform" method="post" enctype="multipart/form-data">
<h3>Upload input file (csv)</h3>
<input type="file" name="input_file" id="input_file">
<br>
<input type="submit" value="Process & Download" name="submit">
</form>
</body>
</html>
sample_input.csv
col1,col2
1,5
2,6
3,7
9,10
6,11
So I can generate the pdf with matplotlib, but I'm not sure how to return this as a pdf to the user (the last step). I'm not married to matplotlib; if there are other plotting libraries which can return plots as pdf, I'm open to that as well.
Not tested (I don't have flask installed on this workstation) but you can save the figure as a pdf by giving the correct extension
fig.savefig('/tmp/some_unique_string.pdf')
and then serve the file with send_from_directory
from flask import send_from_directory
send_from_directory('/tmp', 'some_unique_string.pdf')
Some unsolicited advice:
You can read a csv with pandas.read_csv. This works with a file path or an IO stream and will change numeric columns to an appropriate numeric type automatically.
If you want to switch to a different backend, you need to do so before importing pyplot.
Specifically:
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

unable to render boxplot to html page using python flask

I am trying to render boxplot to html page using python flask. In the code i have imported excel sheet .xls to a data frame. On this dataframe have used pandas boxplot method to get box plot successfully. But when i am trying to render this box plot to html page using flask, i am able to see only box plot grid in html page and not actual box plot.
I have tried to save the box plot image first and then give its image source path in html page. but still unable to render it successfully to html page.
Python code:
from flask import Flask, render_template, send_file, make_response
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from mpl_toolkits.mplot3d import Axes3D
from io import BytesIO
import pandas as pd
plt.style.use('ggplot')
app = Flask(__name__)
#app.route('/do_box_plot/')
def do_box_plot():
df = pd.read_excel('Path\\sfile_name.xls', sheet_name='Sheet1')
df.boxplot(by = 'Programming_Language', column =['Entry_ProgrammingScore'], grid = True)
bytes_image = io.BytesIO()
plt.savefig(bytes_image, format='png')
bytes_image.seek(0)
return send_file(bytes_image, mimetype='image/png')
#app.route('/')
def index():
return render_template("index2.html")
if __name__ == '__main__':
app.run(debug = True)
HTML code:
<!doctype html>
<html>
<body>
<h1>BOX PLOT VISUALIZATIONS FOR TEST SCORES</h1>
<p>BOX PLOTS</p>
<img src='/do_box_plot/' alt="Box Plot" height="442" width="442">
</body>
</html>`enter code here`
Expect to render generated box plot to html page using flask. Could anyone help, thanks.

How to create dynamic plots to display on Flask?

I wish to create dynamic plots based on user input on a flask app. However I am getting the following error:
string argument expected, got 'bytes'
If I use io.BytesIO(), I am not getting this error, but I am not getting the plot on test.html
from flask import Flask
from flask import render_template
import matplotlib.pyplot as plt
import io
import base64
app = Flask(__name__)
#app.route('/plot')
def build_plot():
img = io.StringIO()
y = [1,2,3,4,5]
x = [0,2,1,3,4]
plt.plot(x,y)
plt.savefig(img, format='png')
img.seek(0)
plot_url = base64.b64encode(img.getvalue())
return render_template('test.html', plot_url=plot_url)
if __name__ == '__main__':
app.debug = True
app.run()
Test.html
<!DOCTYPE html>
<html>
<title> Plot</title>
<body>
<img src="data:image/png;base64, {{ plot_url }}">
</body>
</html>
Use BytesIO and later decode()
Working example
from flask import Flask
#from flask import render_template
import matplotlib.pyplot as plt
import io
import base64
app = Flask(__name__)
#app.route('/plot')
def build_plot():
img = io.BytesIO()
y = [1,2,3,4,5]
x = [0,2,1,3,4]
plt.plot(x,y)
plt.savefig(img, format='png')
img.seek(0)
plot_url = base64.b64encode(img.getvalue()).decode()
return '<img src="data:image/png;base64,{}">'.format(plot_url)
if __name__ == '__main__':
app.debug = True
app.run()

Categories

Resources