12

I'm attempting to randomly capture an image from a webcam and then save it to my server, right now i'm using getUserMedia to stream the webcam to video element then I can capture an image to a canvas using a button but i'm not sure how to save that image from the canvas to my server.

Another issue is getUserMedia only works in Chrome, Opera and Firefox, is there any alternative for IE?

This is what i'm currently working with:

    <video id="video" width="640" height="480" autoplay></video>
<button id="snap">Snap Photo</button>
<canvas id="canvas" width="640" height="480"></canvas>
<button id="getBase" onclick="getBase()">Get Base64</button>
<textarea id="textArea"></textarea>

<script>

    // Put event listeners into place
    window.addEventListener("DOMContentLoaded", function() {
        // Grab elements, create settings, etc.
        var canvas = document.getElementById("canvas"),         
        context = canvas.getContext("2d"),
        video = document.getElementById("video"),
        videoObj = { "video": true },
        errBack = function(error) {
        console.log("Video capture error: ", error.code); 
        };

        // Put video listeners into place
        if(navigator.getUserMedia) { // Standard
            navigator.getUserMedia(videoObj, function(stream) {
                video.src = stream;
                video.play();
            }, errBack);
        } else if(navigator.webkitGetUserMedia) { // WebKit-prefixed
            navigator.webkitGetUserMedia(videoObj, function(stream){
                video.src = window.webkitURL.createObjectURL(stream);
                video.play();
            }, errBack);
        }

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

        document.getElementByID("getBase").addEventListener("click", getBase());

    }, false);                  

    function getBase(){
        var imgBase = canvas.toDataURL("image/png");

        document.getElementByID("textArea").value=imgBase;
    }
</script>`

Thanks Heaps

TurtleTopiary
  • 133
  • 1
  • 2
  • 7

2 Answers2

4

You can use canvas.toDataUrl to get a base64 encoded string that you can post as a parameter to a script on your server that will read it in and store as an image file.

Here is a shortened version of an actual implementation of this approach:

<script>
function saveImage(){
    var xmlhttp;
    xmlhttp=((window.XMLHttpRequest)?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP"));
    xmlhttp.onreadystatechange=function(){
        if (xmlhttp.readyState==4){
            if(xmlhttp.status==200){
                //handle success                
            }
        }
    }
    xmlhttp.open("POST",baseURL,true);
    var oldCanvas = under.toDataURL("image/png");
    var params=oldCanvas;
    xmlhttp.setRequestHeader("Content-type", "application/upload");
    xmlhttp.setRequestHeader("Content-length", params.length);
    xmlhttp.setRequestHeader("Connection", "close");
    xmlhttp.send(params);
}
</script>

and here is an example PHP script that accepts the base64 string, converts to a .png, gives it a random filename, and saves:

<?php
if((isset($GLOBALS["HTTP_RAW_POST_DATA"]))){
    //some validation is necessary, this is just a proof of concept
    if(isset($GLOBALS["HTTP_RAW_POST_DATA"])){
        $params=explode('&',$GLOBALS["HTTP_RAW_POST_DATA"]);
        $imgsrc=str_replace(' ','+',$params[0]);
        $im = imagecreatefrompng($imgsrc);
    }
    if($im){
        $background = imagecolorallocatealpha($im, 255,255,255,127);
        imagecolortransparent($im, $background);
        //random file name
        $m = rand(10e16, 10e24);
        $filename=base_convert($m, 10, 36);
        //save image
        imagepng($im, 'images/'.$filename.'.png');
        imagedestroy($im);
        $size = getimagesize('images/'.$filename.'.png');
        $iH=$size[1];
        $iW=$size[0];
        echo "{\"filename\":\"".$filename."\",\"width\":\"".$iW."\",\"height\":\"".$iH."\"}";
    }
}
?>
Robot Woods
  • 5,677
  • 2
  • 21
  • 30
  • I've attempted to use toDataUrl, I've added an onClick to a button to call the following function `function getBase(){ var imgBase = canvas.toDataUrl(); document.getElementByID("textArea").value=imgBase; }` This should be outputting the Base64 string to a textarea i've created. Any clues why it doesnt? – TurtleTopiary Feb 25 '13 at 01:45
  • try specifying a format like so: `.toDataURL("image/png");` maybe? – Robot Woods Feb 25 '13 at 02:41
  • oh, and maybe Url vs. URL? – Robot Woods Feb 25 '13 at 03:37
  • Unfortunately neither of those worked. I've been racking my brain for hours, and its time to go to bed, hopefully a fresh perspective will solve it. – TurtleTopiary Feb 25 '13 at 11:59
  • have you seen this: https://developer.mozilla.org/en-US/docs/WebRTC/taking_webcam_photos I haven't scrubbed through yours to compare, but it looks pretty relevant – Robot Woods Feb 26 '13 at 01:38
  • Yeah, my code already does that, what i'm trying to do is figure out how to save the image to the server. Although the github link does seem to upload to imgur, so maybe there's something in there i could have a look at. – TurtleTopiary Feb 27 '13 at 00:41
  • I did just notice you have `getElementByID` instead of `getElementById` in a couple spots toward the end...but also, when I tried running this to debug, I get nothing, neither video nor anything in the console – Robot Woods Feb 27 '13 at 01:30
  • Ah, think the latter part of that is that I'm on a corporate machine, think the webcam is off limits. – Robot Woods Feb 27 '13 at 01:43
  • Ive managed to get my code working, I stopped working on the above code and started on a cross browser solution to it and i have now managed to display the base64 string using window.alert() i suspect that there may be a limit to the amount of characters that can be used in a text box. now i have to find out a way to convert a base64 string to an image to save on the server – TurtleTopiary Feb 27 '13 at 11:17
  • what server language are you using? I posted a PHP script that you can start from – Robot Woods Feb 27 '13 at 15:45
0

You can use getUserMedia.js or other similar libraries that include a Flash fallback to cover IE. Though Flash has become wildly unpopular recently.

CanIUse.com's stream page has information regarding support for this feature.

As was said in Robot Woods' answer, canvas.toDataUrl will grab the image for you.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Ty-
  • 1