Sitemap / Advertise

Information



Tags



Share

How to capture a picture with mobile and web devices in JavaScript

Advertisement:


read_later

Read Later

Keywords



Keywords



read_later

Read Later

Information

Tags

Share





Advertisement

Advertisement




Definition

In this tutorial, I will show you how to take a photo in JavaScript with WebRTC. In this way, you will be able to collect user information without an effort by letting users take their user images (profile icons) on your website, with compatible devices (mobile and web). In other words, when the user allows the browser or the web application, the website accesses the camera and creates a stream shown on a video tag by which the user can capture a frame as an image using the image tag. I copied and modified the source code of this tutorial from an MDN tutorial, which you can inspect here for further information regarding this tutorial.

For those who are not familiar with, in this tutorial, the source includes an anonymous self-invoking function to avoid global variables(1):

- Anonymous functions do not have a name declaration.

- And, a self-invoking expression is invoked (started) automatically, without being called.

- Function expressions will execute automatically if the expression is followed by ().

- You cannot self-invoke a function declaration (with name).

- You have to add parentheses around the function to indicate that it is a function expression.

Code

JavaScript(2):

- The width and height of the captured photo. We will set the width to the value defined here, but the height will be calculated based on the aspect ratio of the input stream.

- We will scale the photo width to 320px. You can change it in the code.

- The streaming variable indicates whether or not we are currently streaming

- Define required HTML elements for the startup() function.

- In the startup() function, get the needed elements. And, activate a media stream using navigator.mediaDevices.getUserMedia.

- Display the stream in the video element if there is no error.

- Using the canplay event, define the video attributes and height.

- Note: Firefox currently has a bug where the height can't be read from the video, so we will make assumptions if this happens.

- Execute the takepicture() function when the capture button is clicked.

- Run the clearphoto() function after capturing a picture to be able to cacpture a new one.

- In the clearphoto() function, fill the canvas with an indication that none has been captured.

- In the takepicture() function, capture a photo by fetching the current contents of the video and drawing it into the canvas, then converting that to a PNG format data URL to set the src attribute of the photo (image) as the recently captured picture. Note: By drawing it on an offscreen canvas and then drawing that to the screen, it is possible to change its size and/or applyother changes before drawing it.

- Set up the event listener (load) to run the startup function once loading is complete.

HTML:

- Define the canvas to capture a picture.

- Define the application container.

- Define the video container.

- Show the output picture (recently captured).

CSS:

- Design the container by using the display:grid property.

- Style the photo and video elements.

- Hide the canvas.


-------------- JavaScript --------------

(function() {
  // The width and height of the captured photo. We will set the
  // width to the value defined here, but the height will be
  // calculated based on the aspect ratio of the input stream.

  var width = 320;    // We will scale the photo width to this
  var height = 0;     // This will be computed based on the input stream

  // |streaming| indicates whether or not we're currently streaming
  // video from the camera. Obviously, we start at false.

  var streaming = false;

  // The various HTML elements we need to configure or control. These
  // will be set by the startup() function.

  var video = null;
  var canvas = null;
  var photo = null;
  var capture = null;

  function startup() {
    video = document.getElementById('video');
    canvas = document.getElementById('canvas');
    photo = document.getElementById('photo');
    capture = document.getElementById('capture');

    navigator.mediaDevices.getUserMedia({video: true, audio: false})
    .then((stream) => {
      video.srcObject = stream;
      video.play();
    })
    .catch((err) => {
      console.log("An error occurred: " + err);
    });

    video.addEventListener('canplay', (event) => {
      if (!streaming) {
        height = video.videoHeight / (video.videoWidth/width);
      
        // Firefox currently has a bug where the height can't be read from
        // the video, so we will make assumptions if this happens.
      
        if (isNaN(height)) {
          height = width / (4/3);
        }
		
		// Define video settings.
    
        video.setAttribute('width', width);
        video.setAttribute('height', height);
        canvas.setAttribute('width', width);
        canvas.setAttribute('height', height);
        streaming = true;
      }
    }, false);

    capture.addEventListener('click', (event) => {
      takepicture();
      event.preventDefault();
    }, false);
    
    clearphoto();
  }

  // Fill the photo with an indication that none has been
  // captured.

  function clearphoto() {
    var context = canvas.getContext('2d');
    context.fillStyle = "#AAA";
    context.fillRect(0, 0, canvas.width, canvas.height);

    var data = canvas.toDataURL('image/png');
    photo.setAttribute('src', data);
  }
  
  // Capture a photo by fetching the current contents of the video
  // and drawing it into a canvas, then converting that to a PNG
  // format data URL. By drawing it on an offscreen canvas and then
  // drawing that to the screen, we can change its size and/or apply
  // other changes before drawing it.

  function takepicture() {
    var context = canvas.getContext('2d');
    if (width && height) {
      canvas.width = width;
      canvas.height = height;
      context.drawImage(video, 0, 0, width, height);
    
      var data = canvas.toDataURL('image/png');
      photo.setAttribute('src', data);
    } else {
      clearphoto();
    }
  }

  // Set up our event listener to run the startup process
  // once loading is complete.
  window.addEventListener('load', startup, false);
})();

-------------- HTML --------------

<!DOCTYPE html>
<html>
<head>
	<title>JavaScript Image Capturing</title>
	
	<meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="theme-color" content="#ff5c33">
    <meta name="apple-mobile-web-app-status-bar-style" content="#ff5c33">
	
	<link rel="icon" type="image/png" sizes="36x36" href="icon.png">
	
	<link href="https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@300;400&display=swap" rel="stylesheet">
	
	<link rel="stylesheet" href="index.css" type="text/css" media="all">
	
	<script src="index.js"> </script>
</head>
<body>
<h1> JavaScript Image Capturing</h1>
<!-- Define the canvas to capture a picture. -->
<canvas id="canvas"></canvas>
<!-- Define the application container. -->
<div class="container">
  <!-- Define the video container. -->
  <section>
  <video id="video">Video stream not available.</video>
  <button id="capture">Capture</button> 
  </section>
  <!-- Show the output picture (captured). -->
  <section>
  <img id="photo" alt="The screen capture will appear in this box."> 
  </section>
  <!-- Information -->
  <section>
  <p style="color:white;font-size:20px;">You can elicit more information regarding the web application in JavaScript from <a href="/articles/How-to-capture-a-picture-with-mobile-and-web-devices-in-JavaScript/" style="color:#002699;" target="_blank">this tutorial</a> including step-by-step instructions.</p>
  </section>
</div>
</body>
</html>

-------------- CSS --------------

html{background-color:#eb2e00; font-family: 'Roboto Slab'}
h1{color:#002699;font-weight:bold;text-align:center;margin-top:10px;}

.container{display:grid;grid-auto-rows:240px;grid-template-columns:repeat(auto-fill, 320px);grid-gap:100px;justify-content:center;position:relative;width:100%;background-color:transparent;margin-top:20px;}
.container section{width: 340px; height:240px;}

#video{border: 1px solid white; box-shadow: 2px 2px 3px white; width:320px; height:240px;}

#photo{border: 1px solid white;box-shadow: 2px 2px 3px white;width:320px;height:240px;}

#canvas{display:none;}

#capture{display:block;position:relative;margin:auto;bottom:32px;background-color:#002699;border:1px solid white;font-size: 14px;color:white;cursor:pointer;font-weight:bold;outline:none;}
#capture:hover{background-color:#1a53ff;}

Result:

You can inspect a properly-working web application executing the same source code and download it with asset files included in a zipped folder.

JavaScript Image Capturing (web application)

References

(1) https://www.w3schools.com/js/js_function_definition.asp

(2) https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Taking_still_photos