Flask, How can I response the picture on the page - python

I am new to Flask and web development, I want to upload a picture and process it by my deep learning application and then response the processed picture on the page, here is my frame work code
# coding: utf-8
import os
import uuid
import PIL.Image as Image
from werkzeug import secure_filename
from flask import Flask, url_for, render_template, request, url_for, redirect, send_from_directory
ALLOWED_EXTENSIONS = set(list(['png', 'jpg', 'jpeg']))
UPLOAD_FOLDER = '/tmp'
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def process_image(file_path):
"""
resize image to 32x32
:param file_path: file path
:return:
"""
img = Image.open(file_path, mode='r')
return img.resize([32,32], Image.ANTIALIAS)
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
#app.route('/', methods=['GET', 'POST'])
def upload_file():
_path = None
if request.method == 'POST':
_file = request.files['file']
print(_file)
if _file and allowed_file(_file.filename):
filename = secure_filename(_file.filename)
_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
_file.save(_path)
return show_pic(deep_learning(_path))
return '''
<!DOCTYPE html>
<title>Web App/title>
<h1>Deep Learning Web App</h1>
<form action="/" method="POST" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" value="submit" />
</form>
'''
#app.route('/uploads/<filename>')
def uploaded_file(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
if __name__ == '__main__':
app.run()
As you can see it, I have implemented upload picture function and the function deep_learning(path), and it return the path of processed picture, I need to implement function show_pic(), how can I do that?

Create a template with your html skeleton and pass the image path to the render_template() function.
result.html
<html>
<img src="{{ image_path }}">
</html>
Add this to your view function:
return render_template('result.html', image_path=deep_learning(_path))
For this to work your files need to be located in the staticdirectory or a subdirectory.

Or you can define _file(processed file) with None value below form tag check if file not none then show it:
#app.route('/', methods=['GET', 'POST'])
def upload_file():
_path = None
_file = None
if request.method == 'POST':
_file = request.files['file']
print(_file)
if _file and allowed_file(_file.filename):
filename = secure_filename(_file.filename)
_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
_file.save(_path)
return '''
<!DOCTYPE html>
<title>Web App/title>
<h1>Deep Learning Web App</h1>
<form ...>
...
</form>
{% if _file%}
<img src="{{url_for('uploaded_file', filename=_file) }}" >
{% endif %}
'''

Related

Method not allowed 405 Error in Flask Api

I am currently trying to upload a picture and later on process it. But I am getting an 405 error and I don't know how to fix it.
#app.route('/upload')
def upload():
return render_template('upload.html')
#app.route('/uploader', methods = ['GET', 'POST'])
def upload_f():
if request.method == 'POST':
f = request.files['file']
f.save(f.filename)
return 'file uploaded successfully'
The html form
<html>
<body>
<form action = "http://localhost:5000/uploader" method = "POST"
enctype = "multipart/form-data">
<input type = "file" name = "file" />
<input type = "submit"/>
</form>
</body>
</html>
From Miguel Grinberg's Handling File Uploads With Flask tutorial:
import imghdr
import os
from flask import Flask, render_template, request, redirect, url_for, abort, \
send_from_directory
from werkzeug.utils import secure_filename
app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024
app.config['UPLOAD_EXTENSIONS'] = ['.jpg', '.png', '.gif']
app.config['UPLOAD_PATH'] = 'uploads'
def validate_image(stream):
header = stream.read(512) # 512 bytes should be enough for a header check
stream.seek(0) # reset stream pointer
format = imghdr.what(None, header)
if not format:
return None
return '.' + (format if format != 'jpeg' else 'jpg')
#app.route('/')
def index():
files = os.listdir(app.config['UPLOAD_PATH'])
return render_template('index.html', files=files)
#app.route('/', methods=['POST'])
def upload_files():
uploaded_file = request.files['file']
filename = secure_filename(uploaded_file.filename)
if filename != '':
file_ext = os.path.splitext(filename)[1]
if file_ext not in app.config['UPLOAD_EXTENSIONS'] or \
file_ext != validate_image(uploaded_file.stream):
abort(400)
uploaded_file.save(os.path.join(app.config['UPLOAD_PATH'], filename))
return redirect(url_for('index'))
#app.route('/uploads/<filename>')
def upload(filename):
return send_from_directory(app.config['UPLOAD_PATH'], filename)
<html>
<head>
<title>File Upload</title>
</head>
<body>
<h1>File Upload</h1>
<form method="POST" action="" enctype="multipart/form-data">
<p><input type="file" name="file"></p>
<p><input type="submit" value="Submit"></p>
</form>
<hr>
{% for file in files %}
<img src="{{ url_for('upload', filename=file) }}" style="width: 64px">
{% endfor %}
</body>
</html>

Python Flask App - Upload Image and Display

Just getting started with Python Flask App and working with HTML.
I am trying to build a simple image upload page that will display the uploaded image. I have been able to successfully upload and save the file just not display it.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Upload Face with ID</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col">
<h1>Upload Face (filename = face's name (i.e. John_Smith.jpg)</h1>
<hr>
<form action="/upload-image" method="POST" enctype="multipart/form-data">
<div class="form-group">
<label>Select image</label>
<div class="custom-file">
<input type="file" class="custom-file-input" name="image"
id="image">
<label class="custom-file-label" for="image">Select image...</label>
</div>
</div>
<button type="submit" class="btn btn-primary">Upload</button>
</form>
</div>
</div>
</div>
<img src="{{ uploaded_image }}">
</body>
</html>
FLASK APP
import os
from flask import Flask, redirect, jsonify, request, url_for, render_template, flash
app = Flask(__name__)
app.config["IMAGE_UPLOADS"] = "C:/Flask/Upload/"
#app.route("/")
def home():
return render_template("index.html")
# Route to upload image
#app.route('/upload-image', methods=['GET', 'POST'])
def upload_image():
if request.method == "POST":
if request.files:
image = request.files["image"]
# print(image + "Uploaded to Faces")
# flash('Image successfully Uploaded to Faces.')
image.save(os.path.join(app.config["IMAGE_UPLOADS"], image.filename))
filename = os.path.join(app.config["IMAGE_UPLOADS"], image.filename)
print("stored as:" + filename)
return render_template("upload_image.html", uploaded_image=filename)
return render_template("upload_image.html")
if __name__ == "__main__":
app.run()
I have tried to create a separate html for just displaying the image by returning the render_template and passing the uploaded_image=filename.
Ideally I would just like to display the uploaded image at the top of the page or below the submit button once uploaded.
Any help would be much appreciated.
You are not matching your uploads directory to the view. Try this:
#app.route('/upload-image', methods=['GET', 'POST'])
def upload_image():
if request.method == "POST":
if request.files:
image = request.files["image"]
image.save(os.path.join(app.config["IMAGE_UPLOADS"], image.filename))
return render_template("upload_image.html", uploaded_image=image.filename)
return render_template("upload_image.html")
#app.route('/uploads/<filename>')
def send_uploaded_file(filename=''):
from flask import send_from_directory
return send_from_directory(app.config["IMAGE_UPLOADS"], filename)
In your template:
<img src="{{ url_for('send_uploaded_file', filename=uploaded_image) }}" />
In case you just want to upload, analyze, and display the image without saving it to storage, i.e. api and edged image analysis, this example might be a guide for you. Flaskimio
#app.route("/",methods=['GET', 'POST'])
def index():
if request.method == 'POST':
if 'file' not in request.files:
print('No file attached in request')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
print('No file selected')
return redirect(request.url)
if file and check_allowed_file(file.filename):
filename = secure_filename(file.filename)
print(filename)
img = Image.open(file.stream)
with BytesIO() as buf:
img.save(buf, 'jpeg')
image_bytes = buf.getvalue()
encoded_string = base64.b64encode(image_bytes).decode()
return render_template('index.html', img_data=encoded_string), 200
else:
return render_template('index.html', img_data=""), 200
<form method="post" enctype="multipart/form-data">
<p><input type="file" id="file" name="file"><input type=submit value=Upload></p>
<img src="data:image/jpeg;base64,{{ img_data }}" id="img-upload" alt="img_data" class="img-upload"/>
</form>

Error while uploading image file using Flask

Error
while uploading files to my selected folder it raises the following error.
As I am new to flask I am unable to catch the error.
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
app.py
import os
#import magic
import urllib.request
#from app import app
from flask import Flask, flash, request, redirect, render_template
from werkzeug.utils import secure_filename
app = Flask(__name__)
#app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
UPLOAD_FOLDER = '/static'
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route('/')
def upload_form():
return render_template('upload.html')
#app.route('/', methods=['POST'])
def upload_file():
if request.method == 'POST':
# check if the post request has the files part
if 'files[]' not in request.files:
flash('No file part')
return redirect(request.url)
files = request.files.getlist('files[]')
for file in files:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
flash('File(s) successfully uploaded')
return redirect('/')
if __name__ == "__main__":
app.run(debug = True)
upload.html
<!doctype html>
<title>Python Flask Multiple Files Upload Example</title>
<h2>Select file(s) to upload</h2>
<p>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</p>
<form method="post" action="/" enctype="multipart/form-data">
<dl>
<p>
<input type="file" name="files[]" multiple="true" autocomplete="off" required>
</p>
</dl>
<p>
<input type="submit" value="Submit">
</p>
</form>
You should change your code
#app.route('/', methods=['POST', 'GET'])
def upload_file():
if request.method == 'POST':
# check if the post request has the files part
if 'files[]' not in request.files:
flash('No file part')
return redirect(request.url)
files = request.files.getlist('files[]')
for file in files:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
flash('File(s) successfully uploaded')
return redirect('/')
elif request.method == 'GET':
return render_template('upload.html')

Display Submitted Image on Redirected Page via Flask and html [duplicate]

This question already has answers here:
Post values from an HTML form and access them in a Flask view
(2 answers)
Closed 5 years ago.
I'm attempting to create a page that takes in a user-submitted image, and automatically redirects them to a new page where the image is rendered. Much of my code is borrowed from here: How to pass uploaded image to template.html in Flask. But I can't seem to get it to work; I run into a 400: Bad Request. It seems to me that the image is not saving under /static/images, but I am not sure why.
Here is the submission form in index.html:
<form method="POST" action="{{ url_for('predict') }}" enctype="multipart/form-data">
<label for="file-input" class="custom-file-upload">
<i class="fa fa-cloud-upload"></i> Upload Image
</label>
<input name="image-input" id="file-input" type="file" align="center" onchange="this.form.submit();">
</form>
Here is my app.py code:
from flask import Flask, render_template, request, url_for, send_from_directory, redirect
from werkzeug import secure_filename
import os
UPLOAD_FOLDER = '/static/images/'
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'tiff'])
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
#app.route('/')
def index():
return render_template("index.html")
#app.route('/predict/', methods=['POST', 'GET'])
def predict():
if request.method == 'POST':
file = request.files['file']
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('uploaded_file', filename=filename))
return '''
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form action="" method=post enctype=multipart/form-data>
<p><input type=file name=file>
<input type=submit value=Upload>
</form>
'''
#app.route('/show/<filename>')
def uploaded_file(filename):
return render_template('classify.html', filename=filename)
#app.route('/uploads/<filename>')
def send_file(filename):
return send_from_directory(UPLOAD_FOLDER, filename)
if __name__ == '__main__':
app.run(debug=True)
And finally, I try to render it in classify.html, with the following code:
{% if filename %}
<h1>some text<img src="{{ url_for('send_file', filename=filename) }}"> more text!</h1>
{% else %}
<h1>no image for whatever reason</h1>
{% endif %}
Where am I going wrong here?
Looks like I was missing an argument in my input: name=file in index.html. Adding that fixed the error. Altogether, the input line looks like this:
<input id="file-input" name=file type="file" align="center" onchange="this.form.submit();">

how to upload multiple files using flask in python

Here is my code for multiple files upload:
HTML CODE:
Browse <input type="file" name="pro_attachment1" id="pro_attachment1" multiple>
PYTHON CODE:
pro_attachment = request.files.getlist('pro_attachment1')
for upload in pro_attachment:
filename = upload.filename.rsplit("/")[0]
destination = os.path.join(application.config['UPLOAD_FOLDER'], filename)
print "Accept incoming file:", filename
print "Save it to:", destination
upload.save(destination)
But it uploads a single file instead of multiple files.
How to
In the template, you need to add mulitple attribute in upload input:
<form method="POST" enctype="multipart/form-data">
<input type="file" name="photos" multiple>
<input type="submit" value="Submit">
</form>
Then in view function, the uploaded files can get as a list through request.files.getlist('photos'). Loop this list and call save() method on each item (werkzeug.datastructures.FileStorage) will save them at given path:
import os
from flask import Flask, request, render_template, redirect
app = Flask(__name__)
app.config['UPLOAD_PATH'] = '/the/path/to/save'
#app.route('/upload', methods=['GET', 'POST'])
def upload():
if request.method == 'POST' and 'photo' in request.files:
for f in request.files.getlist('photo'):
f.save(os.path.join(app.config['UPLOAD_PATH'], f.filename))
return 'Upload completed.'
return render_template('upload.html')
Furthermore, you may need to use secure_filename() to clean filename:
# ...
from werkzeug.utils import secure_filename
# ...
for f in request.files.getlist('photo'):
filename = secure_filename(f.filename)
f.save(os.path.join(app.config['UPLOAD_PATH'], filename))
# ...
You can also generate a random filename with this method.
Full demo
View:
import os
from flask import Flask, request, render_template
from werkzeug.utils import secure_filename
app = Flask(__name__)
app.config['UPLOAD_PATH'] = '/the/path/to/save'
#main.route('/upload', methods=['GET', 'POST'])
def upload():
form = UploadForm()
if form.validate_on_submit() and 'photo' in request.files:
for f in request.files.getlist('photo'):
filename = secure_filename(f.filename)
f.save(os.path.join(app.config['UPLOAD_PATH'], filename))
return 'Upload completed.'
return render_template('upload.html', form=form)
Form:
from flask_wtf import FlaskForm
from wtforms import SubmitField
from flask_wtf.file import FileField, FileAllowed, FileRequired
class UploadForm(FlaskForm):
photo = FileField('Image', validators=[
FileRequired(),
FileAllowed(photos, 'Image only!')
])
submit = SubmitField('Submit')
Template:
<form method="POST" enctype="multipart/form-data">
{{ form.hidden_tag() }}
{{ form.photo(multiple="multiple") }}
{{ form.submit }}
</form>
More
For better upload experience, you can try Flask-Dropzone.
Your code looks perfect.
I think the only mistake your making is splitting and taking the first value.
And also i dont know about the rsplit(), but the split() works perfect for me.
HTML CODE
<input id="upload_img" name="zip_folder" type="file" multiple webkitdirectory >
PYTHON CODE
#app.route('/zipped',methods = ['GET', 'POST'])
def zipped():
if request.method == 'POST':
f = request.files.getlist("zip_folder")
print f
for zipfile in f:
filename = zipfile.filename.split('/')[1]
print zipfile.filename.split('/')[1]
zipfile.save(os.path.join(app.config['ZIPPED_FILE'], filename))
return render_template('final.html')

Categories

Resources