I am learning flask, trying to write code for edge detection in an image, and let users upload the image, using flask. I believe I'm unable to upload the image correctly, it shows 'no file selected' when I click upload. Here is my code.
import os.path
from io import BytesIO
from tempfile import mkdtemp
from flask import Flask, render_template, flash, request
from flask import send_from_directory, redirect, send_file
from werkzeug.utils import secure_filename
from edge_new import edge_detector
from flask_app import UPLOAD_FOLDER
app = Flask(__name__)
app.secret_key = 'sib'
temp_dir = mkdtemp()
app.config[UPLOAD_FOLDER] = 'temp_dir'
@app.route('/')
def hello():
return "The app is up and running. Go to /edge for functionality"
@app.route('/edge', methods=['POST', 'GET'])
def process_img():
"""
Function takes an image,
finds edges in the image,
returns processed image for download.
"""
if request.method == 'POST':
# Check if image exists
if 'img' not in request.files:
flash("Image not found"), 400
return redirect('/edge')
image = request.files['img']
# Check if image selected
if image.filename == "":
flash("No selected image"), 400
return redirect('/edge')
# Save the image
image_path = secure_filename(image.filename)
path = os.path.join(temp_dir, image_path)
image.save(path)
# Find edges in the image using edge_detector function
processed_image = edge_detector(path) # processed_img is ndarray
# Save the processed image
send_file(BytesIO(processed_image), download_name='processed.jpg', mimetype='image/jpg', as_attachment=True)
return render_template('index.html')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000, debug=True)
I have tried different things. But the error stays. I have tried send_file(), send_from_directory(), cv2.imwrite() but I'm not sure what works. This is my index.html code.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>File Upload Example</title>
<style>
.ok{
font-size: 20px;
}
.op{
font-size: 20px;
margin-left: -70px;
font-weight: bold;
background-color: yellow;
border-radius: 5px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="center">
<h1> Uploading and Returning Files With a Database in Flask </h1>
<form method="POST" action="/edge" enctype="multipart/form-data">
<input class="ok" type="file" name="file">
<button class="op">Submit</button>
</form>
</div>
</body>
</html>
The values of the input fields can be queried using the name attribute. Unfortunately, you have set the attribute to
filefor the input field and are requestingimgfromrequest.files. Either you change the attribute in the html code toimgor ask forfileon the server side.