Capture Photos With Webcam In Javascript (Simple Example)

Welcome to a tutorial on how to capture photos with a webcam in Javascript. Yes, the Stone Age of the Internet is long over, and it is totally possible to take pictures directly using Javascript.

navigator.mediaDevices.getUserMedia({ video: true }).then(stream => {
  // WEBCAM STREAM TO VIDEO
  let v = document.createElement("video");
  v.autoplay = true;
  v.srcObject = stream;
 
  // CAPTURE VIDEO FRAME TO CANVAS
  v.onloadedmetadata = () => {
    let cv = document.createElement("canvas"),
        cx = cv.getContext("2d");
    cv.width = v.videoWidth; cv.height = v.videoHeight;
    cx.drawImage(v, 0, 0, v.videoWidth, v.videoHeight);
  };
});

That’s the gist of it – Ask the user for permission to access the camera, feed the live stream into a video, then capture a video frame onto a canvas. But how do we “save” the photo? Read on for a detailed example.

 

 

TABLE OF CONTENTS

 

DOWNLOAD & NOTES

Here is the download link to the example code, so you don’t have to copy-paste everything.

 

EXAMPLE CODE DOWNLOAD

Source code on GitHub Gist | Example on CodePen

Just click on “download zip” or do a git clone. I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

SORRY FOR THE ADS...

But someone has to pay the bills, and sponsors are paying for it. I insist on not turning Code Boxx into a "paid scripts" business, and I don't "block people with Adblock". Every little bit of support helps.

Buy Me A Coffee Code Boxx eBooks

 

 

JAVASCRIPT WEBCAM CAPTURE

All right, let us now get into the steps and example of how to take a photo with Javascript.

 

TUTORIAL VIDEO

 

PART 1) THE HTML

webcam.html
<!-- (A) VIDEO LIVE FEED -->
<video id="cam-live" autoplay></video>
 
<!-- (B) CONTROLS -->
<div id="cam-controls">
  <input type="button" id="cam-take" class="material-icons"
         value="photo_camera" onclick="webcam.take()" disabled>
  <input type="button" id="cam-save" class="material-icons"
         value="download" onclick="webcam.save()" disabled>
  <input type="button" id="cam-upload" class="material-icons"
         value="upload" onclick="webcam.upload()" disabled>
</div>
 
<!-- (C) SNAPSHOTS -->
<div id="cam-snaps"></div>

Just a simple HTML interface with only a few components:

  1. <video id="cam-live"> is where we will “live stream” the webcam.
  2. As in the introduction, “taking a photo” is simply capturing a frame of the <video> into a <canvas>. Here are 3 possible ways to deal with “save”.
    • Simply insert the <canvas> into the HTML page.
    • Force download as an image file.
    • Upload the image to the server.
  3. An empty area to insert the <canvas>.

 

 

PART 2) INITIALIZE WEBCAM

webcam.js
// (A) INITIALIZE - GET USER PERMISSION TO ACCESS CAMERA
hVid : null, hSnaps :null,
init : () => {
  navigator.mediaDevices.getUserMedia({ video: true })
  .then(stream => {
    // (A1) GET HTML ELEMENTS
    webcam.hVid = document.getElementById("cam-live"),
    webcam.hSnaps = document.getElementById("cam-snaps");
 
    // (A2-1) "LIVE FEED" WEB CAM TO <VIDEO>
    webcam.hVid.srcObject = stream;
 
    // (A2-2) ENABLE BUTTONS
    document.getElementById("cam-take").disabled = false;
    document.getElementById("cam-save").disabled = false;
    document.getElementById("cam-upload").disabled = false;
  })
  .catch(err => console.error(err));
}
window.addEventListener("load", webcam.init);

On window load, webcam.init() will get the user’s permission to access the webcam – navigator.mediaDevices.getUserMedia({ video : true }); We proceed to “enable” the app only when permission is granted.

  • (A1) Self-explanatory, get the HTML elements.
  • (A2) Feed the webcam live stream into the HTML video – webcam.hVid.srcObject = stream;
  • (A3) Enable all the controls.

Take note that getUserMedia() requires https:// to work properly, http://localhost is an exception for testing. Also, if the user denies permission, getUserMedia() will not prompt anymore. You will have to serve your own “how to manually give permission” notice in catch().

 

 

PART 3) TAKE A SNAPSHOT

webcam.js
// (B) SNAP VIDEO FRAME TO CANVAS
snap : () => {
  // (B1) CREATE NEW CANVAS
  let cv = document.createElement("canvas"),
      cx = cv.getContext("2d");
 
  // (B2) CAPTURE VIDEO FRAME TO CANVAS
  cv.width = webcam.hVid.videoWidth;
  cv.height = webcam.hVid.videoHeight;
  cx.drawImage(webcam.hVid, 0, 0, webcam.hVid.videoWidth, webcam.hVid.videoHeight);
 
  // (B3) DONE
  return cv;
},

As in the introduction, this is how we “take a photo” with the webcam.

  • Basically, create an HTML canvas – cv = document.createElement("canvas");
  • Get the 2D context – cx = cv.getContext("2d");
  • Draw the current video frame onto the canvas – cx.drawImage(VIDEO, 0, 0, VID-WIDTH, VID-HEIGHT);

 

PART 4) “SAVE” THE PHOTO

4A) INSERT INTO HTML PAGE

webcam.js
// (C) PUT SNAPSHOT INTO <DIV> WRAPPER
take : () => webcam.hSnaps.appendChild(webcam.snap()),

This is the easiest way to deal with the snapshot… Just insert it into the HTML page somewhere.

 

 

4B) FORCE DOWNLOAD

webcam.js
// (D) FORCE DOWNLOAD SNAPSHOT
save : () => {
  // (D1) TAKE A SNAPSHOT, CREATE DOWNLOAD LINK
  let cv = webcam.snap(),
      a = document.createElement("a");
  a.href = cv.toDataURL("image/png");
  a.download = "snap.png";
 
  // (D2) "FORCE DOWNLOAD" - MAY NOT ALWAYS WORK!
  a.click(); a.remove(); cv.remove();
 
  // (D3) SAFER - LET USERS MANUAL CLICK
  // webcam.hSnaps.appendChild(a);
}

Optionally, we can do a “force download” on the snapshot.

  • Create an HTML anchor link – a = document.createElement("a").
  • Attach the canvas data URL into the anchor tag – a.src = cv.toDataURL("image/png").
  • Finally, a neat trick is to do an a.click() to offer “save as”. But take note, this may not always work due to security constraints.
  • The safer way is to attach the link to the HTML page and let the user manually click to download.

 

4C) UPLOAD SNAPSHOT

webcam.js
// (E) UPLOAD SNAPSHOT TO SERVER
upload : () => {
  // (E1) APPEND SCREENSHOT TO DATA OBJECT
  var data = new FormData();
  data.append("snap", webcam.snap().toDataURL("image/jpeg", 0.6));

  // (E2) UPLOAD SCREENSHOT TO SERVER
  fetch("save.php", { method:"post", body:data })
  .then(res => res.text())
  .then(txt => alert(txt));
}

Finally, upload the snapshot to the server.

save.php
// https://netcell.netlify.com/blog/2016/04/image-base64.html
 
// (A) BASE64 DECODE UPLOADED IMAGE
$data = explode(",", $_POST["snap"]);
$data = base64_decode($data[1]);
 
// (B) SAVE IMAGE
$file = fopen("snap.jpg", "w");
fwrite($file, $data);
fclose($file);
echo "OK";

On the server, just do a base 64 decode and save the uploaded snapshot. This one is in PHP, but you can pretty much “translate” this into any other language.

 

 

EXTRAS

That’s all for this project, and here is a small section on some extras and links that may be useful to you.

 

COMPATIBILITY CHECKS

Works well on all “Grade A” major browsers.

 

LINKS & REFERENCES

 

THE END

Thank you for reading, and we have come to the end of this guide. I hope that it has helped you with your project, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

4 thoughts on “Capture Photos With Webcam In Javascript (Simple Example)”

  1. Parables Botlnoel

    This is by far the most excellent tutorial blog I have ever visited. Bookmarked for future visits.

  2. Nishal Beegamudre

    Can you please send the code such that the captured screenshot can be shown on one part of the html page as soon as screenshot button will be clicked?

Leave a Comment

Your email address will not be published. Required fields are marked *