0

I have a canvas image which I need to upload to the server.

I also save the path to MySql. The MySql part of the code works perfectly. When I upload the canvas one of the following two things happen: 1) It does not upload image. 2) If it does upload, it has 0KB.

In HTML I put the image in a hidden area, to upload. The rest of the HTML is basically getting the image.

HTML:

<form method="post" accept-charset="utf-8" name="form1">
<input name="hidden_data" id='hidden_data' type="hidden"/>
</form>


<form name="sub" id="sub" method="post" onsubmit="return uploadEx();" action="camtestinsert.php">
<video id="video" width="640" height="480" autoplay></video>
<button id="snap" class="sexyButton" type="button">Snap</button>
<canvas id="canvas" name="canvas" width="640" height="480"></canvas>
<input type="submit" name="Submit" value="Submit" />
</form>

Javascript:

<script>

    // Put event listeners into place
    window.addEventListener("DOMContentLoaded", function() {
        // Grab elements, create settings, etc.
        var canvas = document.getElementById('canvas');
        var context = canvas.getContext('2d');
        var video = document.getElementById('video');
        var mediaConfig =  { video: true };
        var errBack = function(e) {
            console.log('An error has occurred!', e)
        };

        // Put video listeners into place
        if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
            navigator.mediaDevices.getUserMedia(mediaConfig).then(function(stream) {
                video.src = window.URL.createObjectURL(stream);
                video.play();
            });
        }

        /* Legacy code below! */
        else if(navigator.getUserMedia) { // Standard
            navigator.getUserMedia(mediaConfig, function(stream) {
                video.src = stream;
                video.play();
            }, errBack);
        } else if(navigator.webkitGetUserMedia) { // WebKit-prefixed
            navigator.webkitGetUserMedia(mediaConfig, function(stream){
                video.src = window.webkitURL.createObjectURL(stream);
                video.play();
            }, errBack);
        } else if(navigator.mozGetUserMedia) { // Mozilla-prefixed
            navigator.mozGetUserMedia(mediaConfig, function(stream){
                video.src = window.URL.createObjectURL(stream);
                video.play();
            }, errBack);
        }

        // Trigger photo take
        document.getElementById('snap').addEventListener('click', function() {
            context.drawImage(video, 0, 0, 640, 480);
        });
    }, false);

</script>

and

<script>
        function uploadEx() {
            var canvas = document.getElementById("canvas");
            var dataURL = canvas.toDataURL("image/png");
            document.getElementById('hidden_data').value = dataURL;
            var fd = new FormData(document.forms["form1"]);

            var xhr = new XMLHttpRequest();
            xhr.open('POST', 'camtestinsert.php', true);

            xhr.upload.onprogress = function(e) {
                if (e.lengthComputable) {
                    var percentComplete = (e.loaded / e.total) * 100;
                    console.log(percentComplete + '% uploaded');
                    //alert('Photo Uploaded Succesfully');
                }
            };

            xhr.onload = function() {

            };
            xhr.send(fd);
        };
    </script>

PHP:

$upload_dir = "Child_Images/";
$img = $_POST['hidden_data'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = $upload_dir . "Photo_ID_UniqueSerial:_" . $photo_ID . ".png";
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';
  • Check the browser console is the data being sent up? – Lawrence Cherone Dec 11 '17 at 02:01
  • Where is `$photo_ID` defined? – NewToJS Dec 11 '17 at 02:05
  • @NewToJS - It is defined in the original code. I can add it if needed, but I use `hash` to create the photo_id based on other variables such as time etc. – CharlesWashington Dec 11 '17 at 02:10
  • @LawrenceCherone. It seems so. Honestly I am not very familiar with browser console. I did the check and the only concern is A form was submitted in the windows-1252 encoding which cannot encode all Unicode characters, so user input may get corrupted. To avoid this problem, the page should be changed so that the form is submitted in the UTF-8 encoding either by changing the encoding of the page itself to UTF-8 or by specifying accept-charset=utf-8 on the form element. – CharlesWashington Dec 11 '17 at 02:12
  • encoding is not the problem, as its base64 encoded before sending up `toDataURL`, you need to research on how to use the browser console alittle, so as to check if the data being sent up, or if the js is broken or your vars are empty, The PHP side looks familiar as a copy and paste from all the *save canvas to server* [1](https://stackoverflow.com/questions/18376578/how-to-change-the-upload-directroy-in-php), [2](https://stackoverflow.com/questions/42822733/ajax-post-has-empty-values-on-the-server), it will blindly create a file without checking its even an image or even if its a POST request. – Lawrence Cherone Dec 11 '17 at 02:24
  • [3](https://stackoverflow.com/questions/25036253/how-to-save-a-image-coded-in-data-uri).. in the php do `print_r($_POST['hidden_data']);` check the console if it's empty then you have the reason. – Lawrence Cherone Dec 11 '17 at 02:30
  • You are not blocking the default POST of your form, so your XHR is not sent. You need to add `return false;` at the end of your `uploadEx` function to do so. But don't send a base64 version of your canvas, moreover when you already send this through a FormData. Instead send it as Multipart. [See this Q/A](https://stackoverflow.com/questions/34711715/phpjs-how-to-do-fileuploads-in-html-form-as-content-type-multipart-via-js/34713226#34713226) Also, why use two `
    `?
    – Kaiido Dec 11 '17 at 03:32
  • And finally, don't use `URL.createObjectURL(MediaStream)`, which will block the input device, instead use directly `video.srcObject = stream`. – Kaiido Dec 11 '17 at 03:34
  • @Kaiido. The first `form` is to send the canvas data to a hidden area in order to save. – CharlesWashington Dec 12 '17 at 07:02
  • @Kaiido. Thanks for the note. I changed `URL.createObjectURL(MediaStream)` to `video.srcObject = stream` – CharlesWashington Dec 12 '17 at 07:14

0 Answers0