Welcome folks I am back with another blog post. In this post we will be building a complete Webcam filter and Picture App with the help of WebRTC and Canvas in Javascript. At the end of this post you have build a really nice application to show to your peers and friends. Let’s get started with the Application.

First of all I would like to tell you about the application and what it can do or not. The application name will be VidSnapper. In VidSnapper we will be displaying the webcam of your laptop or computer onto the browser and we can also take snapshot of webcam and render that photo onto the browser also. Also there are some cool little filters available in the application which we can apply to the webcam and also to the photo which is taken of the webcam. So guys get ready it will be fun to make this application from start to finish.

As you can see in the following figure above this will be the application interface in which first of all you can see the title of the application below that we have the webcam video running on the browser and below that we have the button to take snapshot of the webcam and below that you can see the select option in which there are different filters available which we can apply to webcam and also to the snapshot and after that there is also a button available to clear out the photos taken by the user.

As you can see in the following figure you can apply cool little filters to make the application even more attractive and fun to play with and after applying the respective filter you can take the snapshot of the webcam.

Step -1 : Create the index.html file to hold the markup of the application. Copy paste below code into your favourite text editor

<!DOCTYPE html> <html> <head> <title>VidSnapper</title> <link rel="stylesheet" href="style.css"> <body> <div class="navbar"> <h1>VidSnapper</h1> </div> <div class="top-container"> <video id="video">No streaming available...</video> <button id="photo-button" class="btn btn-dark">Take Photo</button> <select id="photo-filter" class="select"> <option value="none">Normal</option> <option value="grayscale(100%">Grayscale</option> <option value="sepia(100%)">Sepia</option> <option value="invert(100%)">Invert</option> <option value="hue-rotate(90deg)">Hue</option> <option value="blur(10px)">Blur</option> <option value="contrast(200%)">Contrast</option> </select> <button id="clear-button" class="btn btn-light">Clear</button> <canvas id="canvas"></canvas> </div> <div class="bottom-container"> <div id="photos"> </div> </div> </body> <script src="script.js"></script> </head> </html>

This is the index.html file as you can see in the following code we have a navbar which is holding the title of the application and after that we have a div having a class of top container which contains the video (webcam) which is to be rendered on to the browser and below that we have the button to take snapshot of the webcam and after that we have a select element which contains different kinds of filters which can be applied to the webcam and image and lastly we have the canvas element in the top container in which we will holding the image which is taken when we press the take photo button and lastly we have the bottom container which contains a div element which will actually hold the photos for us in a grid manner as shown below.

Step-2 : Create stylesheet file called as style.css into your code editor. Copy paste the entire code given below.

body{ margin:0; padding:0; font-family:Arial, Helvetica, sans-serif; background:#000 url('background.jpg'); overflow-x:hidden; } .navbar{ background:#333; padding:15px; height:40px; color:#fff; } .navbar h1{ text-align:center; margin:0; } .top-container{ width:500px; margin:30px auto; } .btn{ display:block; width:100%; padding:10px; margin-bottom:5px; } .btn-dark{ background:#333; color:#fff; border:#666 1px solid; } .btn-light{ background:#f4f4f4; color:#333; border:#ccc 1px solid; } .select{ height:40px; background:#333; color:#fff; padding:3px; width:100%; border:1px #666 solid; margin-bottom:10px; } .bottom-container{ max-width:960px; margin:auto; padding:10px; } #photos{ display:grid; grid-template-columns: repeat(3,1fr); grid-gap:10px; } #photos img{ width:100%; border:3px #fff solid; } #canvas{ display:none; }

This is the entire stylesheet code of the application. After pasting code into the editor you will see the application look more prettier and attractive. After that we will creating the script.js which will be main business logic of the application.

let width =500, height =0, filter= "none", streaming=false; // fetching elements from dom const video = document.getElementById('video'); const canvas = document.getElementById('canvas'); const photos = document.getElementById('photos'); const clearButton = document.getElementById('clear-button'); const photoButton = document.getElementById('photo-button'); const photoFilter = document.getElementById('photo-filter');

In the initial lines of javascript code we are declaring some global variables which we will be use in the script later and after that we are fetching the elements by using the famous method in javascript called as getElementById() and through this process we are able to fetch elements and store it in respective variables for further use in the script.

// get the webcam onto the browser navigator.mediaDevices.getUserMedia({video:true,audio:false} ) .then(function(stream){ video.srcObject = stream; video.play(); }) .catch(function(err){ console.log(`Error: ${err}`); });

The above Javascript code does the magic of displaying the webcam of laptop/computer on to the browser. Displaying webcam in browser is not that difficult as you can see in the code we are just using mediaDevices Api method which is available in all modern browsers and it is fully compatible in all the browsers. It will everytime work with any browser.

// play when ready video.addEventListener('canplay',function(e){ if(!streaming){ height = video.videoHeight / (video.videoWidth/width); video.setAttribute('width',width); video.setAttribute('height',height); canvas.setAttribute('width',width); canvas.setAttribute('height',height); streaming = true; } },false);

In the above code, we are just attaching a canplay event listener to the video element so that if the event fires i.e when the video is ready to play the webcam streaming we can set the width and height of the video and canvas element. The width is fixed but the height is calculated by the following formula in the code as you can see. After that we are just setting the respective attributes to set the width and height of the video and canvas respectively.

/ attaching event to photo button photoButton.addEventListener('click',function(e){ takePicture(); e.preventDefault(); },false);

In the above code we are just attaching onClick event on the take photo button and inside this we are calling the takePicture method which we will be making later in the script.

// function to take picture function takePicture() { const context = canvas.getContext('2d'); if(width && height) { canvas.width = width; canvas.height = height; // draw the image of the webcam on the canvas context.drawImage(video,0,0,width,height); const imgUrl = canvas.toDataURL('image/png'); // create image element const img = document.createElement('img'); // set img src img.setAttribute('src',imgUrl); img.style.filter = filter; photos.appendChild(img); } }

In the above code we have defined the takePicture method in this first of all we are getting the context of the 2D canvas and then setting width and height of the canvas and then drawing the image on the canvas by using the method drawImage passing in the x and y coordinates, video element and also the width and height of the canvas and after that we are generating the image url which is to be rendered into the canvas window and then we are creating the image element and after that setting the src attribute to that generated image url and after that appending it to the div element photos which actually displays the photos in the grid manner.

Paste this code on the onCreate method of your activity. This code generally means we are setting google sign in options which includes requesting the id token and requesting some standard information from the user which includes email address,profile picture and username of the user.You can also read the documentation to customize this according to your application.

// attaching event to photo filter section photoFilter.addEventListener('change',function(e){ filter = e.target.value; video.style.filter = filter; e.preventDefault(); }); // event to clear out the photos

In the above code we are attaching onChange event listener to the select element which will select the actual filter which is to be applied to the video and the photo element. First of all in this we are fetching the value which is selected by the user and then manipulating the style.filter property of the video element to store the filter value selected by the user.

// event to clear out the photos clearButton.addEventListener('click',function(e){ photos.innerHTML = ''; filter = 'none'; video.style.filter = filter; photoFilter.selectedIndex=0; }); // function to take picture

In the above code we are attaching the onClick event Listener to the clear button which will actually clear all the photos which is taken by clicking the take photo button so in this we are first of all manipulating the innerHtml property of the photos elements and making it empty and after that we are reseting the filter property to none or normal and lastly we also reset the filter property of the video element to normal and also the index of the selectFilter to default i.e. 0. That’s all guys our script.js is complete. The below code is the full version of the script. Just copy paste the whole script into your code editor.

// declare global variables let width =500, height =0, filter= "none", streaming=false; // fetching elements from dom const video = document.getElementById('video'); const canvas = document.getElementById('canvas'); const photos = document.getElementById('photos'); const clearButton = document.getElementById('clear-button'); const photoButton = document.getElementById('photo-button'); const photoFilter = document.getElementById('photo-filter'); // get the webcam onto the browser navigator.mediaDevices.getUserMedia({video:true,audio:false} ) .then(function(stream){ video.srcObject = stream; video.play(); }) .catch(function(err){ console.log(`Error: ${err}`); }); // play when ready video.addEventListener('canplay',function(e){ if(!streaming){ height = video.videoHeight / (video.videoWidth/width); video.setAttribute('width',width); video.setAttribute('height',height); canvas.setAttribute('width',width); canvas.setAttribute('height',height); streaming = true; } },false); // attaching event to photo button photoButton.addEventListener('click',function(e){ takePicture(); e.preventDefault(); },false); // attaching event to photo filter section photoFilter.addEventListener('change',function(e){ filter = e.target.value; video.style.filter = filter; e.preventDefault(); }); // event to clear out the photos clearButton.addEventListener('click',function(e){ photos.innerHTML = ''; filter = 'none'; video.style.filter = filter; photoFilter.selectedIndex=0; }); // function to take picture function takePicture() { const context = canvas.getContext('2d'); if(width && height) { canvas.width = width; canvas.height = height; // draw the image of the webcam on the canvas context.drawImage(video,0,0,width,height); const imgUrl = canvas.toDataURL('image/png'); // create image element const img = document.createElement('img'); // set img src img.setAttribute('src',imgUrl); img.style.filter = filter; photos.appendChild(img); } }

Congratulations we are done making Webcam filter and Picture App from scratch. All the source code of the Application is available below to download. Thanks for reading this post and if you like reading this and wants to read more of this please subscribe the blog below to get all the notications.