Easily Access Webcam with CamMan.js
I recently read How You Can Build an HTML Photobooth App by
John Robinson and thought it was a great article. He explains some of the basic
math behind image effects such as grayscale, sepia, and others. I thought it
was interesting enough to try to make my own demo. He includes some basic code
to access the webcam via WebRTC, but I wanted something a little more robust.
I looked for good libraries out there to do this, but couldn't find exactly
what I wanted. I decided to roll my own using
leemachin/say-cheese
as a basis to start with. CamMan.js
has been enhanced to support multiple canvas outputs, each of which may be
manipulated separately per frame. CamMan.js is very lightweight with the
minified source code weighing in at 3.7 KB.
CamMan.js is available on GitHub. You can check out my Photobooth example app which I was able to easily create using CamMan.js.
Support
One thing the library does is include shims for vendor prefixed methods needed to access the webcam and microphone array using WebRTC. The demo should work in recent versions of Chrome, Firefox, and Opera. If you have any problems, please leave me a comment below. Safari and IE support is not there yet as of the time of this writing, but the shims include the prefixes for possible future support.
The Basics
The simplest thing to get your webcam video onto a page.
<html>
<head>
<title>Hello CamMan</title>
<script type="text/javascript" src="CamMan.js"></script>
</head>
<body>
<div id="container"></div>
<script type="text/javascript">
var camMan = new CamMan({ container: 'container' });
camMan.start();
</script>
</body>
</html>
By default passing in a container id with the constructor options will cause the source video element to be injected into the container. If you'd rather have a canvas element, you can wait until the webcam has been initialized and then get a canvas. CamMan.js exposes an event-based API:
var camMan = new CamMan();
camMan.on('start', function () {
camMan.getCanvas('container', function (canvas) {
var ctx = canvas.getContext('2d');
var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
/** Manipulate array of pixel data -- imgData.data */
ctx.putImageData(imgData)
});
});
The callback passed to camMan.getCanvas
is executed once per frame, allowing
you to manipulate each frame before it is drawn to the canvas. Using this
capability I was able to quickly create my Photobooth app using image filter
effects.
Some Fun Stuff
Here is an example filter which will invert the colors of each pixel:
var inverse = function inverse(imageData) {
var data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
data[i] = 255 - data[i];
data[i + 1] = 255 - data[i + 1];
data[i + 2] = 255 - data[i + 2];
}
return imageData;
};
And here is another that converts a video to grayscale by setting the color components of each pixel to be the average value of all three color channels.
var grayScale = function grayScale(imageData) {
var data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
var red = data[i];
var green = data[i + 1];
var blue = data[i + 2];
var average = (red + green + blue) / 3;
data[i] = data[i + 1] = data[i + 2] = average;
}
return imageData;
};
Resources
Sharing
Categories
Tags
blog comments powered by Disqus