This post has been sitting around unfinished since April so I thought I should finish it and get it out there.
In this post I am going to show how you can capture an image from a webcam via JavaScript and convert it to a Data URI which can then be saved in a database or displayed in an IMG tag.
Note: This is more of a proof of concept rather than a best practices example so the code is a bit messy and hacked together from various sources.
I have only tested this on Safari for iOS 6 and latest Chrome with a webcam. It may or may no work in other browsers.
All explanations for the the code and markup are in the code comments, so please read them for more detail.
Here is a basic HTML page with some simple CSS for this demonstration:
#container {
margin: 0px auto;
width: 500px;
height: 375px;
border: 10px #333 solid;
}
#videoElement {
width: 500px;
height: 375px;
background-color: #666;
}
#canvas {
width: 500px;
height: 375px;
background-color: #CCC;
}
In the body we add the following elements:
<!-- On iOS 6 we can use the file select input with the following attributes to capture an image from the camera -->
<input id="fileselect" accept="image/*" type="file" />
<!-- For devices that support getUserMedia and have a webcam we can display the feed in a video element -->
<div id="container"><video id="videoElement" autoplay="autoplay" width="300" height="150">
</video></div>
<!-- Selected image will be draw to a canvas -->
<canvas id="canvas" width="500" height="375"></canvas>
<!-- Used to capture frame from webcam video feed -->
<input id="save" type="button" value="Save" />
<!-- Or alternatively added to an img tag -->
<img id="imgtag" alt="capture" width="500" height="375" />
<!-- For the JavaScript below -->
<script></script>
Finally we’ll add the following Javascript to the script tag inside the body:
var video = document.querySelector("#videoElement");
// check for getUserMedia support
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia;
if (navigator.getUserMedia) {
// get webcam feed if available
navigator.getUserMedia({video: true}, handleVideo, videoError);
}
function handleVideo(stream) {
// if found attach feed to video element
video.src = window.URL.createObjectURL(stream);
}
function videoError(e) {
// no webcam found - do something
}
var v,canvas,context,w,h;
var imgtag = document.getElementById('imgtag'); // get reference to img tag
var sel = document.getElementById('fileselect'); // get reference to file select input element
// when DOM loaded, get canvas 2D context and store width and height of element
v = document.getElementById('videoElement');
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
w = canvas.width;
h = canvas.height;
function draw(v,c,w,h) {
if(v.paused || v.ended) return false; // if no video, exit here
context.drawImage(v,0,0,w,h); // draw video feed to canvas
var uri = canvas.toDataURL("image/png"); // convert canvas to data URI
// console.log(uri); // uncomment line to log URI for testing
imgtag.src = uri; // add URI to IMG tag src
}
document.getElementById('save').addEventListener('click',function(e){
draw(v,context,w,h); // when save button is clicked, draw video feed to canvas
});
// for iOS
// create file reader
var fr;
sel.addEventListener('change',function(e){
var f = sel.files[0]; // get selected file (camera capture)
fr = new FileReader();
fr.onload = receivedData; // add onload event
fr.readAsDataURL(f); // get captured image as data URI
})
function receivedData() {
// readAsDataURL is finished - add URI to IMG tag src
imgtag.src = fr.result;
}
That is all the code that’s required. The new HTML5 APIs make it very quick and easy to do some interesting stuff!