Image not uploading using flask (shows no file selected when I click upload). IDE shows 302

42 Views Asked by At

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>

2

There are 2 best solutions below

0
Detlef On

The values of the input fields can be queried using the name attribute. Unfortunately, you have set the attribute to file for the input field and are requesting img from request.files. Either you change the attribute in the html code to img or ask for file on the server side.

1
Vinay Davda On

I checked your code by running it. Your endpoint /edge is trying to get img in if condition and block:

if 'img' not in request.files:
    flash("Image not found"), 400
    return redirect('/edge')

image = request.files['img']

While you are sending file as name="file"

<input class="ok" type="file" name="file">

You can correct it by updating index.html input code line: (See name="img" instead of name="file")

<input class="ok" type="file" name="img">