Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload an Image and Display it back as a response using Flask

I'm a beginner in front end development, and have to do a small web app in Flask for a project.

I have written a Flask app that lets you upload an image using HTML Forms and then displays the image back to the user when you hit Upload. I need to modify this such that the image does not get saved to a folder in the project directory everytime a user uploads it. Basically, the app should send the uploaded image back in the body of the response.

Here is my code so far:

UploadTest.py

import os


from uuid import uuid4

from flask import Flask, request, render_template, send_from_directory

app = Flask(__name__)
# app = Flask(__name__, static_folder="images")



APP_ROOT = os.path.dirname(os.path.abspath(__file__))

@app.route("/")
def index():
    return render_template("upload.html")

@app.route("/upload", methods=["POST"])
def upload():
    target = os.path.join(APP_ROOT, 'images/')
    print(target)
    if not os.path.isdir(target):
            os.mkdir(target)
    else:
        print("Couldn't create upload directory: {}".format(target))
    print(request.files.getlist("file"))
    for upload in request.files.getlist("file"):
        print(upload)
        print("{} is the file name".format(upload.filename))
        filename = upload.filename
        destination = "/".join([target, filename])
        print ("Accept incoming file:", filename)
        print ("Save it to:", destination)
        upload.save(destination)

    return render_template("complete.html", image_name=filename)

@app.route('/upload/<filename>')
def send_image(filename):
    return send_from_directory("images", filename)

if __name__ == "__main__":
    app.run(port=8080, debug=True)

upload.html - creates an upload form

<!DOCTYPE html>
<html>
<head>
<title>Upload</title>
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
</head>
<body>

<form id="upload-form" action="{{ url_for('upload') }}" method="POST" enctype="multipart/form-data">

    <strong>Files:</strong><br>
    <input id="file-picker" type="file" name="file" accept="image/*" multiple>
    <div id="msg"></div>
    <input type="submit" value="Upload!" id="upload-button">
</form>
</body>
<script>

    $("#file-picker").change(function(){

        var input = document.getElementById('file-picker');

        for (var i=0; i<input.files.length; i++)
        {

            var ext= input.files[i].name.substring(input.files[i].name.lastIndexOf('.')+1).toLowerCase()

            if ((ext == 'jpg') || (ext == 'png'))
            {
                $("#msg").text("Files are supported")
            }
            else
            {
                $("#msg").text("Files are NOT supported")
                document.getElementById("file-picker").value ="";
            }

        }


    } );

</script>
</html>

complete.html - displays the image from the folder in which it has been saved after a user hits "upload"

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
Uploaded
<img src=" {{url_for('send_image', filename=image_name)}}">
</body>
</html>

I have tried researching quite a bit but was unable to find anything other than deleting the folder after it has been displayed (which I didn't think is the right way of solving the question at hand). I'd really appreciate any help in this matter, and if there is a better solution than what my code currently does, I'd love to learn more!

Thank you! :)

like image 205
Richa Netto Avatar asked Mar 16 '17 04:03

Richa Netto


1 Answers

Please check below code can help you.Copy the below code in upload.html in templates folder.

<!DOCTYPE html>

<html>
<head>
<link class="jsbin" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.0/jquery-ui.min.js"></script>
<meta charset=utf-8 />

 <script src="{{ url_for('static', filename='upload.js') }}"></script>

<style>
  article, aside, figure, footer, header, hgroup, 
  menu, nav, section { display: block; }
</style>
</head>
<body>
<form action = "http://127.0.0.1:5000/uploader" method = "POST" 
 enctype = "multipart/form-data">
  <input type='file' name = 'file' onchange="readURL(this);" />
    <img id="blah" src="#" alt="your image" />
 <input type = "submit"/>
</form>
</body>
</html>

Copy the below code in upload.js file in static folder

function readURL(input) {
if (input.files && input.files[0]) {
    var reader = new FileReader();

    reader.onload = function (e) {
        $('#blah')
            .attr('src', e.target.result)
            .width(150)
            .height(200);
    };

    reader.readAsDataURL(input.files[0]);
}
}

Now copy the below code in a python file

from flask import Flask, render_template, request
from werkzeug import secure_filename
import os 

app = Flask(__name__)

app.config['UPLOAD_FOLDER'] = 'D:/Projects/flask/image_upload/images/'

@app.route('/')
def upload_f():
   return render_template('upload.html')

@app.route('/uploader', methods = ['GET', 'POST'])
def upload_file():
   if request.method == 'POST':
      f = request.files['file']
      f.save(os.path.join(app.config['UPLOAD_FOLDER'],secure_filename(f.filename)))
      return 'file uploaded successfully'

# if __name__ == '__main__':
app.run(debug = True)

Above piece of code will help you to browse and display the image on html page and as well save the image on your disk at desired location.

like image 119
Shubham S. Naik Avatar answered Nov 11 '22 23:11

Shubham S. Naik