11

I've created an image using canvas. I want to append the exact image file in the form data and not the url. This is my code.

<video></video>

<button type="button" onclick="turnOn()">turn on cam</button>
<button type="button" onclick="takeSnapshot()">capture image</button>


<script>
    function turnOn() {
         document.getElementsByTagName('video')[0].play();

         var video = document.querySelector('video')
          , canvas;

        if (navigator.mediaDevices) {
           navigator.mediaDevices.getUserMedia({video: true})
            .then(function(stream) {
              video.src = window.URL.createObjectURL(stream);
            })
            .catch(function(error) {
              document.body.textContent = 'Could not access the camera. Error: ' + error.name + " " + error.message;
            });
        }
    }

    function takeSnapshot() {
        var video = document.querySelector('video')
          , canvas;

        var img = document.querySelector('img') || document.createElement('img');
        var context;
        var width = video.offsetWidth
            , height = video.offsetHeight;

        canvas = canvas || document.createElement('canvas');
        canvas.width = width;
        canvas.height = height;

        context = canvas.getContext('2d');
        context.drawImage(video, 0, 0, width, height);

        img.src = canvas.toDataURL('image/png');
        document.body.appendChild(img);

        var fd = new FormData(document.forms[0]);
        fd.append("image", img);

        $.ajax({
            type: "POST",
            enctype: 'multipart/form-data',
            url: "/api/file/upload",
            data: fd,
            processData: false,
            contentType: false,
            cache: false,
            success: (data) => {
                alert("yes");
            },
            error: function(xhr, status, error) {
                  alert(xhr.responseText);
                }
        });
    }

</script>

It's appending the blob file "����..." And I want it to append the exact image file. I haven't used this before and can't seem to understand other tutorials. Hoping you could help me. Thank you so much!!!

Edit: I already edited the code and tried to append the same image I'm appending on the body. But it's not working..

CaptainHarry
  • 193
  • 1
  • 2
  • 8
  • Can you please post your html as well? There isn't enough here for me to reproduce the problem. See [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve) – Rocky Sims Oct 14 '18 at 04:41
  • @RockySims Hello!! I've already edited it and posted the whole code. Hoping you could help me. I want to append the exact image on the form data. I tried it with blob and it's working. But when I append the image file it's not. – CaptainHarry Oct 14 '18 at 07:01
  • Shouldn't it be `fd.append("image", img.src);` not `fd.append("image", img);`? Also I'm not clear on what you mean by "I want to append the exact image" as opposed to the "blob file". What would the "exact image" look like as post data if not a blob of garbled looking text that represents the image data? – Rocky Sims Oct 14 '18 at 07:33
  • Also, I feel like the code you've posted isn't quite the same as what you're running locally since when I run it (after adding jquery) I see the post data as `image: [object HTMLImageElement]` not a blob like "����...". – Rocky Sims Oct 14 '18 at 07:37
  • I edited it. Because I'm saving the file locally after sending it through ajax. I tried getting the string and save it to my local file and it works but the file that is being saved is in blob "����..." text. After appending the "img" to the body, I also want to pass the image through ajax in image.png format. :) I tried using img.src and it returns an error which is "Required request part 'image' is not present". – CaptainHarry Oct 14 '18 at 07:54
  • This is my controller: public String uploadMultipartFile(@RequestParam("image") MultipartFile file) { /...functions.../ } – CaptainHarry Oct 14 '18 at 07:55
  • @RockySims I tried sending the blob file and it works. But I'm getting an error when I tried to append it in png format. And also, thank you for responding. :) – CaptainHarry Oct 14 '18 at 07:58

1 Answers1

14

You might try converting the based 64 encoded inline image returned by canvas.toDataURL('image/png') to the same kind of File object you get from an <input id="file" type="file"></input> element when using document.getElementById("file").files[0] and append that to fd.

To give that a try, change

var fd = new FormData(document.forms[0]);
fd.append("image", img);

$.ajax({
    type: "POST",
    enctype: 'multipart/form-data',
    url: "/api/file/upload",
    data: fd,
    processData: false,
    contentType: false,
    cache: false,
    success: (data) = > {
        alert("yes");
    },
    error: function(xhr, status, error) {
        alert(xhr.responseText);
    }
});

to

fetch(img.src)
    .then(res => res.blob())
    .then(blob => {
        const file = new File([blob], "capture.png", {
            type: 'image/png'
        });
        var fd = new FormData();
        fd.append("image", file);
        $.ajax({
            type: "POST",
            enctype: 'multipart/form-data',
            url: "/api/file/upload",
            data: fd,
            processData: false,
            contentType: false,
            cache: false,
            success: (data) => {
                alert("yes");
            },
            error: function(xhr, status, error) {
                alert(xhr.responseText);
            }
        });
    });
Rocky Sims
  • 3,523
  • 1
  • 14
  • 19