I am making a web app that generates a QR code using input from the user and saves it into a specified file. After the QR code is saved, It should display the generated QR code in a small box next to the input box.
I am attempting to do this by having a GET submit button that goes to this route but I receive an error every time I click it.
The first block of code is for receiving the input and making a QR code out of it, and the second is my attempt to send back the finished PNG and display it.
Python Code:
#app.route('/', methods= ['POST'])
def textfield():
text = request.form['text']
processed_text = text
if processed_text == '':
flash("Please enter a value!")
else:
QR(processed_text)
return render_template('base.html')
#app.route('/QR', methods= ['GET'])
def QRimage(text):
im = Image.open(f'{text}.png')
data = io.BytesIO()
im.save(data, "PNG")
encoded_img_data = base64.b64encode(data.getvalue())
img_data = encoded_img_data.decode('utf-8')
return render_template('base.html', value=img_data)
Here is the HTML to attempt to display the image:
<img id="picture" src="data:image/jpeg;base64,{{ img_data }}">
And the GET button that routes to /QR:
<form action="/QR" method="GET">
<button type="submit" type="button">QR Button</button>
Flask looks for static files in the static folder which is the default.
use flask.send_from_directory(directory, filename, **options) if you want to serve files from another directory. This is a secure way to quickly expose static files.
#app.route('/QR', methods= ['GET'])
def QRimage(text):
return send_from_directory(app.config['UPLOAD_FOLDER'], filename);
Reference:
API — Flask Documentation (1.1.x) (2021). Available at: https://flask.palletsprojects.com/en/1.1.x/api/#flask.send_from_directory (Accessed: 24 April 2021).
Related
I am using Pytesseract OCR for text detection and I am using a jupyter notebook to run it right now so the output is just popping up as another window. My output for the program is an image. Basically, I am trying to allow the user to input their own image and then the program will output another image on the website.
I am trying to do this but I am getting an error when I try loading the website. Here is my code:
import cv2
import matplotlib.pyplot as plt
from flask import Flask, request, Response
pytesseract.pytesseract.tesseract_cmd = 'C:\\Camera_Flask_App-main\\Tesseract\\tesseract.exe'
def pytess(img):
hImg,wImg,_ = img.shape
boxes = pytesseract.image_to_boxes(img)
for b in boxes.splitlines():
print(b[0])
b = b.split(' ')
x,y,w,h= int(b[1]),int(b[2]),int(b[3]),int(b[4])
cv2.rectangle(img,(x,hImg-y),(w,hImg-h),(0,0,255), 2)
cv2.putText(img,b[0],(x,hImg-y+25), cv2.FONT_HERSHEY_COMPLEX,1,(50,50,255),2)
##Detecting Words
hImg,wImg,_ = img.shape
boxes = pytesseract.image_to_data(img)
for x,b in enumerate(boxes.splitlines()):
if x!=0:
b = b.split()
if len(b)==12:
x,y,w,h= int(b[6]),int(b[7]),int(b[8]),int(b[9])
cv2.rectangle(img,(x,y),(w+x,h+y),(0,0,255), 2)
cv2.putText(img,b[11],(x,y), cv2.FONT_HERSHEY_COMPLEX,1,(50,50,255),2)
return img
# Initialize Flask application
app = Flask(__name__)
# POST request for running OCR
#app.route('/', methods=['GET', 'POST'])
def run_ocr():
image = request.files["image"]
#Read the image via file.stream, returns PIL image (may need to convert)
img = Image.open(image.stream)
# run ocr on image (you will need to update your function to return img)
processed_img = pytess(img)
# prepare image for response
_, img_encoded = cv2.imencode('.png', processed_img)
response = img_encoded.tostring()
# return png img with OCR shown
return Response(response=response, status=200, mimetype='image/png')
return '''
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form method=post enctype=multipart/form-data>
<input type=file name=image>
<input type=submit value=Upload>
</form>
'''
if __name__ == '__main__':
app.run()
This is the error I am getting when I launch the site (not even put any picture):
error image
I got some feedback from another person and he said "You need to make sure that when you send the request you have the format as “multipart/form-data” with the “image” field set as the file" and when I asked him to help me fix the code he said, "I can’t change it here. It isn’t part of the code. Once you deploy the Flask server, it would be in the actual request to the server that you need to distinguish the data format". I am not really sure how to do this.
Can anyone help? Thanks!
I have a trained model for speech synthesis. It creates audio correctly everytime from textarea in html page and saves it static folder. But sometimes when i return audio from folder it brings the older one. It doesnt happen everytime but i couldnt find solution.
html audio code
{% if my_audio %}
<audio controls>
<source src="{{ url_for('static', filename='a.wav') }}" type="audio/wav"/>
</audio>
{% endif %}
flask code if you needed
from flask import Flask, render_template, request
import inference
app = Flask(__name__)
app.static_folder = 'static'
#app.route("/")
def home():
return render_template("index.html")
#app.route("/sentez", methods = ["POST"])
def sentez():
if request.method == "POST":
metin = request.form["metin"]
created_audio = inference.create_model(metin)
return render_template("index.html", my_audio = created_audio)
if __name__ == "__main__":
app.run();
This issue arises due to the browser fetching the file from its cache instead of the static folder, after the first run. You need to append a parameter to to the audio file's URL (or query string) that would be unique, so that it will fetch a new copy from the static folder. I suggest appending number of milliseconds elapsed, getTime() method does this in JavaScript.
The JavaScript equivalent for changing the source is as follows:
function playAudio() {
var audioFile = new Audio('./a.wav');
//URL is ./a.wav
audioFile.play()
}
change this to
function playAudio() {
var audioFile = new Audio('./a.wav?' + new Date().getTime());
//URL becomes something like ./a.wav?1623483193060
audioFile.play()
}
You can find out how to do the same in Flask for modifying the statement
{{ url_for('static', filename='a.wav') }}
Currently I am using flask and heroku to deploy my website but i need my webpage show random photo from img directory currently my code look like this
import os
import random
imgs = os.listdir('static/img')
imgs = ['img/' + file for file in imgs]
imgrand = random.sample(imgs,k=5)
#app.route('/')
def index():
return render_template('index.html', imgrand=imgrand)
And my HTML code look like this
{% for img in imgrand %}
<img src="static/{{img}}" alt="{{imgL}}" style="width:100%">
{% endfor %}
So long it work fine in my local machine ,but it only random picture only once when start flask run command in terminal. My goal is to make my web page random picture everytime when refresh webpage without going to end terminal session and start flask run command all over again.
In this case imggrand variable only takes one sample at the beggining of the program, for repeating the process everytime you refresh the webpage you need to put imggrand inside the endpoint.
I recommend you to learn about endpoints and designing the workflow starting with this: https://flask.palletsprojects.com/en/1.1.x/quickstart/#rendering-templates
I am trying to set up a side project on DigitalOcean, and I am using the git framework from https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xvii-deployment-on-linux to get started.
Within this framework, I have added code within one of the flask routes (/explore) in which I generate a plot with matplotlib, and I want to return this plot as an object when I render the template as the return function of this route. I don't need to save the plot if it can be sent to the template without doing so (e.g with io.BytesIO()), but I have been unable to get the syntax correct to use this approach and get the plot to render in the resulting template.
While my attempts with io.BytesIO() have been unsuccessful, if it would help to output the results with that approach, please let me know how to best utilize it, and I will attempt to run this code with the suggested changes and report the results.
Thank you in advance!
I have tried to save the file and send it to the template, as well as sending the file data via BytesIO(), but neither approach has worked for me.
Below is my attempt to save the file to the static directory and send the image to the template, but a solution that works in this environment with io.BytesIO() or similar without saving the file would be even better.
Here is the code that I added to the explore route in /app/main/routes.py to save the plot image to the static directory and return the path to the template:
new_graph_name = url_for('static', filename='tmp_png.png')
plt.savefig(new_graph_name)
return render_template('index.html', url=new_graph_name)
Here is the code that I added to the index.html template:
{% if url %}
<img src={{ url }} alt="Chart" height="42" width="42" />
{% endif %}
In terms of saving the plot and then displaying it, could you try something similar to the code the below? This has worked for me recently.
In routes.py:
#app.route("/")
def index():
new_graph_name = 'tmp_png'
plt.savefig('static/images/' + new_graph_name)
return render_template("index.html", new_graph_name=new_graph_name)
In index.html:
<img src="{{ url_for('static', filename='images/' + new_graph_name + '.png') }}"
With Bytes.IO I think I've tried something like this before:
In routes.py:
import io
from io import BytesIO
import base64
img = io.BytesIO()
fig.savefig(img)
img.seek(0)
buffer = b''.join(img)
b2 = base64.b64encode(buffer)
barplot=b2.decode('utf-8')
I cannot remember how I displayed it in the .html template but could it just be a matter of passing it as a variable?
I use python with bottle framework. When the user clicks a button, the server should generate file and let the user download it. When the user downloads it completely, the server should delete this file.
Is there any way to achieve this?
I found the way by this page (flask solution) and this page(hooks plugin) and this page(Forced Download).
this is my solution:
put hook "after_request" function into route function
part of my code:
download page templete (only one button):
<form id="export" calss="etable" method="POST" action="/download">
<input type="submit" name="export" value="export">
</form>
download page
#route('/download')
def download():
output = template('download',template_lookup=['./views'])
return output
click button(generate file and redirect to download)
#route('/download',method = 'POST')
def downloadPost():
zipname = zipFolder('./temp') #create files
if zipname is not None:
return redirect('/download/'+zipname)
else:
abort(500,'error.')
Forced Download function (put hook in this part.)
#route('/download/<filename:path>')
def download_file(filename):
#hook('after_request')
def delFiles():
del('./temp/',filename) #delete file function
return static_file(filename, root='./temp/', download=filename)