Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python flask ajax get image - last EDIT is the issue

Since yesterday I am trying to understand how I can use the encoded base64 image from a certain view in an other view.

I need to replace my form.company_logo_image_path.data which is the original image with the new image which is resized. The new resized image is sent via AJAX to a new view.

Here my AJAX:

var dataurl = canvas.toDataURL("image/png");

$.ajax({
  type: "POST",
  url: "/profil/unternehmen-bearbeiten/resize-image",
  data:{
    a: dataurl
  }
}).done(function() {
  console.log('sent');
});

I created a new view where the image is decoded and stored in the body variable:

@app.route('/profil/unternehmen-bearbeiten/resize-image', methods=["POST"])
def resize_image():
    data_url = request.values['a']  
    content = data_url.split(';')[1]
    image_encoded = content.split(',')[1]
    body = base64.decodestring(image_encoded.encode('utf-8'))
    return body

I tested this by saving the image to a folder on my local machine and it worked so the body variable stores the resized image correctly.

Now I need this image to be sent to an other view where it will be uploaded to AWS3 and I will use this image instead of form.company_logo_image_path.data:

@app.route('/profil/unternehmen-bearbeiten', methods=["GET", "POST"])
@login_required
@check_confirmed
def edit_company():
    the_company = Company.query.filter_by(users_id=current_user.id).first()

    form = EditCompanyForm(obj=the_company)
    used_file = the_company.company_logo_image_path

    if form.validate_on_submit():

        form.populate_obj(the_company)    

        imagedata = resize_image()
        print "The", imagedata

        if form.company_logo_image_path.data:           
            upload_image_to_aws('baubedarf', "userimages/", form.company_logo_image_path, the_company,'company_logo_image_path', the_company.company_name)

# ...

The problem here is I get a Bad Request site if I try to access the result of the resize_image function from the first view. How can I access the new Image?


I am working on this problem since yesterday and it is the biggest issue I ever had so far, here is my old question with my progress: Old question with my progress and tries

EDIT

It doesnt matter what I try, sending to "/profil/unternehmen-bearbeiten" also results in a bad request error.

Requesting the data a anywhere results in a bad request:

try:
    print request.values['a']
except Exception as e:
    print "error", e

The Exception here is the Bad Request

Also requesting the canvas itself results in a bad request, the console in the browser doesnt tell me something useful which I can use/understand. Its the same as in the console in Eclipse, it gets a 400 Bad Request in the route where I try to send to:

try:
    print request.form['uploading_canvas']
except Exception as e:
    print "error 1", e

enter image description here

EDIT

Finally I made some serious progress! I was trying to request the data in if form.validate_on_submit():. I put the code now outside if form.validate_on_submit(): and I can now request the data, I am still getting problems, but from here I can keep on working!

if request.method == 'POST':
    print "post"
    file_data = request.values['a']
    imagedata = resize_image(file_data)
    print "The", type(imagedata)

if form.validate_on_submit():
    # ...

I am getting again a Bad Request here, but I understand now why. form.validate_on_submit(): itself is a POST request aswell, so I need the correct if condition and it will work (I guess).

Basically the problem is: My ajax request and the form.validate_on_submit(): in the route where I am sending to are both POST requests, that is why I am getting Bad Request so often, there is a conflict. I was trying creating a custom form checkbox. I was trying moving the code and different other if conditions. I simply dont get it.

My recent tries:

    """
if form.company_check_it.data == True:
    print "post 1"
    file_data = request.values['a']
    imagedata = resize_image(file_data)
    print "The", type(imagedata)
else:
    print "post 3"
"""

"""
if request.method == 'POST':
    print "post"
    file_data = request.values['a']
    imagedata = resize_image(file_data)
    print "The", type(imagedata)
"""

if form.validate_on_submit():
    print "post 2"

    """
    if form.company_check_it.data == True:
        print "post 1"
        file_data = request.values['a']
        imagedata = resize_image(file_data)
        print "The", type(imagedata)
    else:
        print "post 3"
    """

    if request.method == 'POST':
        print "post"
        file_data = request.values['a']
        imagedata = resize_image(file_data)
        print "The", type(imagedata)

    form.populate_obj(the_company)    

    """
    data_url = request.values['a']
    print data_url
    content = data_url.split(';')[1]
    image_encoded = content.split(',')[1]
    body = base64.decodestring(image_encoded.encode('utf-8'))
    print type(body)   
    """  
like image 994
Roman Avatar asked Mar 15 '17 10:03

Roman


1 Answers

I think you need a different approach with this, as you seem to be getting mixed up with all the data passing between HTML forms/Flask views/Javascript.

Basically, your Javascript should be populating a hidden field in your Form with the dataURL of the resized image from the canvas. This will then be submitted to your Flask view, where you can upload the data to S3.

Below is a simple example application illustrating what I mean.

app.py

from flask import Flask, url_for, redirect, render_template
from flask_wtf import Form
from wtforms import HiddenField
import base64


class EditCompanyForm(Form):
    resized_image = HiddenField()


app = Flask(__name__)
app.config['SECRET_KEY'] = '1234'


@app.route("/", methods=['GET', 'POST'])
def index():

    form = EditCompanyForm()

    if form.validate_on_submit():
        if form.resized_image.data:
            data = resize(form.resized_image.data)
            print("Uploading to AWS")
            # upload_image_to_aws(data, other_variables_as_needed)

        return redirect(url_for('index'))

    return render_template('index.html', form=form)


def resize(data_url):

    content = data_url.split(';')[1]
    image_encoded = content.split(',')[1]
    body = base64.decodestring(image_encoded.encode('utf-8'))
    return body


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

templates/index.html

<!DOCTYPE HTML>
<html>
  <head>
    <style>
      body {
        margin: 0px;
        padding: 0px;
      }
    </style>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

    <script>

    $(document).ready(function () {

      var canvas = document.getElementById('myCanvas');
      var context = canvas.getContext('2d');
      var imageObj = new Image();

      imageObj.onload = function() {
        context.drawImage(imageObj, 69, 50);
      };

      imageObj.src = '{{ url_for('static', filename='darth-vader.jpg') }}';

      $("#submit").click(function() {
          var dataurl = canvas.toDataURL("image/png");
          $("#resized_image").val(dataurl);
      });

    });

    </script>

  </head>
  <body>
    <canvas id="myCanvas" width="578" height="400"></canvas>

    <form method="post">

        {{ form.hidden_tag() }}

        <input type="submit" value="Save" id="submit" name="submit" />

    </form>

  </body>
</html>
like image 134
Matt Healy Avatar answered Sep 26 '22 03:09

Matt Healy