0

I am using flask (python) to host a interface that allows the user to upload an image, and use a slider to change the value of a variable in a function that reduces noise in an image.

The slider works but the problem is I have to reload the page every time that I want to see the change in value on the updated image.

how can I add a slider that will update the image in real time so I won't have to continuously reload the page to see the changes?

(If the slider is at 0 I want it to to look how the image did when it first uploaded)

I'm doing some searching and it looks like I would use jquery or something but I don't know how to implement it

thanks for reading

app.py:

import os
from flask import Flask, render_template, request, send_from_directory,url_for, session, redirect
import cv2
import shutil


app = Flask(__name__)

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


app.config['UPLOAD_FOLDER'] = os.path.join(APP_ROOT, 'images')
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0

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

@app.route('/images/<filename>')
def uploadfile(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'],filename)

@app.route('/home')
def home():
    return render_template("completed.html", imgSrc="images/" + session.get('imgSrc') , message=session.get('message'))

@app.route("/upload" , methods = ['POST'])
def upload():
    target = os.path.join(APP_ROOT, 'images')

    if request.method == 'POST':

        if not os.path.isdir(target):
            os.mkdir(target)

        for file in request.files.getlist("file"):
            filename = file.filename

            destination = "/".join((target, filename))

            file.save(destination)

            filename = destination

            org = open(filename, 'rb')

            base = os.path.basename(filename)

            dir = os.path.dirname(filename)

            filename_cp = os.path.splitext(base)[0]

            filename_cp = "cp_"+filename_cp+os.path.splitext(base)[1]

            destination2 = dir+"/"+filename_cp
            file.save(destination2)

            cpy = open (destination2, 'wb')
            shutil.copyfileobj(org, cpy)

            session['image'] = filename
            session['filename'] = filename
            session['imgSrc'] = os.path.basename(destination)
            session['cimgsrc'] = os.path.basename(destination2)
            session['cpimg'] = destination2

            print("session", session)

    return render_template("completed.html",imgSrc="images/"+session.get('imgSrc'))

@app.route("/imgp/nr", methods=['post'])
def nr():
    print(session)

    img = cv2.imread(session.get('cpimg'), 0)
    #threshold = 40
    threshold = float(request.form['slider'])
    cv2.threshold(img, threshold, 255, cv2.THRESH_BINARY, img)
    print (session['cpimg'])
    cv2.imwrite(session.get('cpimg'),img)
    session['message'] = "NR is done!"
    session['imgSrc'] = os.path.basename(session['cpimg'])
    return redirect(url_for('home', op='nr'))

if __name__ =="__main__":
    app.secret_key = "abcdefghijklmnopqrstuvwxyz"
    app.run(port = 4555, debug = True)

upload.html:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Upload</title>

</head>

<form id ="upload-form" action="{{ url_for ('upload') }}" method = "POST" enctype="multipart/form-data">
    <input type="file" name="file" accept = image/* multiple>
    <p>Drag your files here or click in this area.</p>
    <button type ="submit" value="Upload"> Upload</button>


</form>


<body>

</body>
</html>

completed.hmtl (where the slider and uploaded image is):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1> file uploaded</h1>
<img src="{{imgSrc}}" style="height:200px;width:300px;"/>
<h2>{{message}}</h2>


<form action ="imgp/nr" method = "post">
    <input type="range" min={{min}} max={{max}} value={{max}} class="slider" id="myRange" name="slider">
    <input type="submit" value="Apply ga">
</form>

</body>
</html>
BVOM
  • 91
  • 1
  • 6

1 Answers1

1

The short answer is you will need to do this with Javascript/jQuery. There's a similar question here covers two ways to do it:

  1. Either load the (base64 converted) image via ajax; or

  2. Change the src of the image on the page using jquery, to have it reload.

You will likely need to change a few parts of your code to get this all working, but it may be something along the lines of:

app.py:

Change your nr() function to GET, and return a base64 encoded image, see here for example (upload_file() function)

completed.html:

Add an ajax (the following is jquery) call to /imgp/nr that changes the display of the image on the page, when the slider is changed. For example:

...
<img id="yourImage" style="height:200px;width:300px;">
...


<script type="text/javascript">
$("#myRange").change(function(){
    var sliderVal = $(this).val();
    $.ajax({ 
        medthod: 'POST',
        url:'/imgp/nr/',
        data: JSON.stringify({slider: sliderVal}),
        success: function(data){
            $("#yourImage").attr('src', 'data:image/png;base64, ' + data);
        }
    });
});
</script>

This code may need some fixing, I don't have much time to make it perfect sorry. Hopefully you get the idea!

djnz
  • 2,021
  • 1
  • 13
  • 13
  • I'm looking at the post you linked but I kind of still don't understand how it would change the value of threshold in my app.py to showcase that change from the slider – BVOM Jun 04 '19 at 23:39
  • I've added a little more detail, hope it gets you started – djnz Jun 05 '19 at 01:17
  • sorry for more questions, but I tried to implement what you posted above but I'm still running into problems. is .change(function) supposed to change the nr? which is the value of threshold? – BVOM Jun 05 '19 at 13:21
  • `.change` is the [jquery event handler](https://api.jquery.com/change/), so when the range slider is changed, that function will run. You will need to get the value of the slider to submit to your endpoint. I'll make a quick edit above the `$.ajax` and `url` to demo. – djnz Jun 05 '19 at 21:07