Hey there, hope you are doing great!
In this blog, we will build a simple application to capture photos from your machine using JavaScript Web API.
Let's get started.
What is Web API?
- API stands for Application Programming Interface.
- A Web API is an application programming interface for the Web.
- A Browser API can extend the functionality of a web browser.
- A Server API can extend the functionality of a web server
All browsers have a set of built-in Web APIs to support complex operations and help to access data.
Here, we will use - MediaDevices interface
The MediaDevices interface provides access to connected media input devices like cameras and microphones, as well as screen sharing.
In essence, it lets you obtain access to any hardware source of media data.
Read here to know more about it.
Screenshot of our application
Check out the live demo here.
Step 1 - Building UI
<div class="container p-3 my-3">
<div class="row">
<h3>Capture Photo using JavaScript Web API</h3>
<button class="btn btn-primary" id="start-camera">
<i class="fas fa-camera"></i>
Start Camera
</button>
</div>
<div class="row align-items-center">
<div class="col-lg-5">
<video id="video" autoplay></video>
</div>
<div class="col-lg-2 justify-content-center">
<button class="btn btn-primary" id="click-photo">
<i class="fas fa-camera-retro"></i>
Click Photo
</button>
<button class="btn btn-secondary" id="resetBtn">
<i class="fas fa-sync-alt"></i>
Reset
</button>
</div>
<div class="col-lg-5" id="dataurl-container">
<canvas id="canvas" width="420" height="240"></canvas>
</div>
</div>
<div class="row justify-content-end p-3" id="downloadDIV">
<input class="form-control" type="text" id="fileName" placeholder="Enter File Name">
<a class="btn btn-link" id="downloadID">Download</a>
</div>
</div>
Step 2 - The JavaScript
Get the ID of the elements,
let camera_button = document.querySelector("#start-camera");
let video = document.querySelector("#video");
let click_button = document.querySelector("#click-photo");
let canvas = document.querySelector("#canvas");
let dataurl_container = document.querySelector("#dataurl-container");
let downloadBtn = document.querySelector("#downloadID");
let resetBtn = document.querySelector("#resetBtn");
let fileName = document.querySelector("#fileName");
Step 3
Add click event to the start button, here media devices Web API is called,
Syntax
var promise = navigator.mediaDevices.getUserMedia(constraints);
The constraints parameter is a MediaStreamConstraints object with two members: video and audio, describing the media types requested.
Either or both must be specified.
camera_button.addEventListener('click', async function() {
let stream = null;
try {
stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: false });
}
catch(error) {
alert(error.message);
return;
}
video.srcObject = stream;
video.style.display = 'block';
camera_button.style.display = 'none';
click_button.style.display = 'block';
});
The browser asks for permission, select allow. Here video view has been highlighted since the camera is on ;)
Step 4
Capture your photo, on the Click Photo button,
click_button.addEventListener('click', function() {
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
let image_data_url = canvas.toDataURL('image/jpeg');
downloadBtn.href = image_data_url; //For downloading the photo
dataurl_container.style.display = 'block';
downloadBtn.style.display = 'block';
fileName.style.display = 'block';
resetBtn.style.display = 'block';
});
Step 5 - Download the photo
The base64 canvas is stored in the variable image_data_url, with which we added as href attribute to the <a> tag.
To write a custom file name add the below code,
fileName.addEventListener('keyup', function() {
downloadBtn.download = fileName.value + '.jpeg';
});
Step 6 - Reset the current photo and continue capturing
resetBtn.addEventListener('click', function() {
dataurl_container.style.display = 'none';
downloadBtn.download = '';
downloadBtn.style.display = 'none';
resetBtn.style.display = 'none';
fileName.value = '';
fileName.style.display = 'none';
});
Get the full code from my GitHub here.
Happy learning!!