News 1st December 2015 | By: marcinkawa Capture/manipulate video in canvas [HTML5] With HTML5 it is now possible to directly capture video from the camera and stream it to the element. It is also possible to mirror the video to a element, you can do some really cool stuff like apply filters, take pictures similar to photobooth applications and so on. Here is an example of a simple application which captures the video from the camera and allows you to take a photo and save it as png. First let’s start with a simple HTML5 page and all the necessary elements which will host the streaming of the video and the storing of the picture. [code language=”html”] <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> </head> <body> <div> <video id="camera_video" width="400" height="300" autoplay></video> <canvas id="camera_filter_canvas" width="400" height="300"></canvas> <img id="camera_image" src="" width="400" height="300" /> </div> </body> </html> [/code] You can ask the browser to request an access to the user’s camera by using the getUserMedia call. Unfortunately not all the browsers yet support this, some of the browsers have different naming for this, let’s make sure we can support as many browsers as we can. [code language=”javascript”] navigator.getUserMedia = (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia); [/code] This will handle all main browsers and assign the detected media device as the `navigator.getUserMedia`. The next stage would be to actually request access to the camera by calling getUserMedia. This function takes 3 arguments, the first argument is an object with the properties you want to access to, in our case we only want to access the video, hence the audio is set to false. The second and third arguments are callback functions, respectively for successful stream and error. [code language=”javascript”] var video = document.getElementById(‘camera_video’); if(navigator.getUserMedia){ navigator.getUserMedia( { video: true, // stream video audio: false // in this example we don’t need to capture audio }, function(stream){ // success function video.src = window.URL.createObjectURL(stream); }, function(error){ // error function alert(‘Something went wrong. (error code ‘ + error.name + ‘)’); return; } ); } [/code] By changing the source attribute of the video element we are now effectively directly streaming from the camera to the browser. We will use our a element for this and copy the video stream to the canvas and apply a filter on it. We will be targeting 60fps. [code language=”javascript”] var canvas = document.getElementById(‘camera_filter_canvas’); var context = canvas.getContext(‘2d’); var w = canvas.width; var h = canvas.height; video.addEventListener(‘play’, function(){ setInterval(function(){ if(video.paused || video.ended) return; context.drawImage(video, 0, 0, w, h); // draw actual video frame }, 1000/60); }); [/code] Now let’s try and add some filters to our video such as GrayScale filter. [code language=”javascript”] video.addEventListener(‘play’, function(){ setInterval(function(){ if(video.paused || video.ended) return; context.drawImage(video, 0, 0, w, h); // draw actual video frame var pixels = context.getImageData(0, 0, w, h); var d = pixels.data; for(var i=0; i<d.length; i+=4){ var r = d[i]; var g = d[i+1]; var b = d[i+2]; // CIE luminance for the RGB var v = 0.2126*r + 0.7152*g + 0.0722*b; d[i] = d[i+1] = d[i+2] = v } context.putImageData(pixels, 0, 0); }, 1000/60); }); [/code] Its also possible to take a screenshoot of that video by using `toDataURL` property of the element and assign the result and use that result as a source for element. [code language=”javascript”] var img = document.getElementById(‘camera_image’); var img_base64 = canvas.toDataURL("image/png"); img.src = img_base64; [/code] As you can see this is really simple, yet very powerful. The full example from this post can be found on CodePen. Tags: canvas, getUserMedia, HTML5, Javascript, toDataURL, video