0

I'm trying to crop the image and send it to the server.

I have code as follows:

<div id="result">
     <img id="photo" src="http://localhost:63342/frontend/assets/images/audi.png?_ijt=hj4q47j1ghucndpqm4t9j0p08r"/>
     <canvas id="canvas"></canvas>
     <canvas id="crop-area" class="hide"></canvas>
</div>

The important one in this case is the second canvas <canvas id="crop-area" class="hide"></canvas>.

When I'm done with selecting (cropping photo) I have the above canvas with a rect inside, as follows:

enter image description here

That with blue border is the cropped part which I want to upload to the server. I tried it with Html2Canvas but that library takes the screenshot of the div, thus in my case it uploads everything to the server, but I want only the blue part, thus only this:

enter image description here

The code for uploading is as follows:

function renderMessage(wrapper, message){
    if(wrapper.classList.contains("fadeOut")) wrapper.classList.remove("fadeOut");
    if(wrapper.classList.contains("fadeIn")) wrapper.classList.remove("fadeIn");

    wrapper.classList.add("fadeIn");
    setTimeout(function(){
        wrapper.classList.add("fadeOut");
    }, 4000);
    wrapper.innerHTML = message;
    save_button_label.classList.remove('hide');
    save_button_spinner.classList.add('hide');
}

function upload_to_server(canvasData){

    return fetch(api_url, {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({photo: canvasData})
    }).then(function (value) {
        if(value.ok){
            return value.json().then(function (response) {
                if(response.status === "success"){
                    drag = false;
                    buttons_shown = false;
                    selection_editing_buttons.classList.add("hide");
                    selection_editing_description.classList.remove("hide");
                    update = true;
                    rectangles = [];
                    return renderMessage(success, upload_success_msg);
                }else{
                    return renderMessage(errors, upload_error_msg);
                }
            })
        }
    }).catch(function (reason) {
        return renderMessage(errors, upload_error_msg);
    })

}

function onSaveChanges(){
    save_button_label.classList.add('hide');
    save_button_spinner.classList.remove('hide');

    console.log(crop_rect.startX); // I have start position x
    console.log(crop_rect.startY); // I have start position x
    console.log(crop_rect.w);      // I have width
    console.log(crop_rect.h);      // I have height

    html2canvas(document.getElementById("result")).then(function(canvas) {
        var canvasData = canvas.toDataURL("image/" + image_type + "");
        upload_to_server(canvasData)
    });
}

Is there any possibility to get the cropped part and upload it to the server. I have start position x, start position y and width and height of the cropped part.

Any idea?

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
Boky
  • 11,554
  • 28
  • 93
  • 163
  • First crop the image using a canvas (See: https://stackoverflow.com/q/26015497). Then save the image and POST it to your server (See: https://stackoverflow.com/q/13198131) – scagood Feb 15 '18 at 11:20

1 Answers1

0

Canvas toBlob polyfill (better look for a better option):

if (!HTMLCanvasElement.prototype.toBlob) {
    Object.defineProperty(HTMLCanvasElement.prototype, "toBlob", {
        value: function(callback, type, quality) {
            const binStr = atob(this.toDataURL(type, quality).split(",")[1]), len = binStr.length, arr = new Uint8Array(len);
            for (let i = 0; i < len; i++) arr[i] = binStr.charCodeAt(i);
            callback(new Blob([arr], { type: type || "image/png" }));
        }
    });
}

Uploading canvas to server:

croppedCanvas.toBlob((blob) => {
    formData.append("file", blob);
    fetch("/"  /* api_url in your case */, {
        method: "POST",
        body: formData
    }).then(r => r.json()).then(d => {
        //Your logic, in my case I get JSON from server
    });
}, "image/jpeg", 0.90);
velour
  • 28
  • 1
  • 7