Webcam Capture and File Upload with HTML JavaScript jQuery

Introduction

In modern web applications, providing users with multiple options for inputting images can enhance the user experience and improve functionality. One such feature is the ability to capture a photo using a webcam or upload an image file from the user's device. This article walks through creating an interface that offers both these capabilities using HTML, JavaScript, and jQuery.

HTML Structure

The HTML structure for this interface consists of a video element for the live webcam feed, a canvas for displaying the captured image, and a file input element for uploading images. Additionally, buttons are provided for capturing the photo and triggering the final upload process.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Webcam Capture or File Upload</title>
</head>
<body>
  <div id="camera-container">
    <video id="video" width="640" height="480" autoplay></video>
    <button id="capture-btn">Capture Photo</button>
    <canvas id="canvas" width="640" height="480"></canvas>
  </div>
  <div id="upload-container" style="display: none;">
    <input type="file" id="file-input" accept="image/*">
  </div>
  <button id="finalUpload">Final Upload</button>
  <script src="https://code.jquery.com/jquery-3.7.1.js"></script>
  <script src="script.js"></script>
</body>
</html>

JavaScript Functionality

The JavaScript code handles three main tasks: accessing the webcam, capturing the photo, and handling file uploads. The script uses the MediaDevices API to access the user's webcam and displays the live feed in the video element. If the webcam is unavailable, the script hides the camera container and shows the file upload input.

const cameraContainer = document.getElementById('camera-container');
const uploadContainer = document.getElementById('upload-container');
const video = document.getElementById('video');
const canvas = document.getElementById('canvas');
const captureBtn = document.getElementById('capture-btn');
const fileInput = document.getElementById('file-input');
navigator.mediaDevices.getUserMedia({ video: true })
  .then(stream => {
    video.srcObject = stream;
    video.play();
  })
  .catch(err => {
    // If access to webcam is denied or not available, show file upload
    alert('No webcam found, showing file upload input.');
    cameraContainer.style.display = 'none';
    uploadContainer.style.display = 'block';
  });
captureBtn.addEventListener('click', () => {
  const context = canvas.getContext('2d');
  context.drawImage(video, 0, 0, canvas.width, canvas.height);
  canvas.toBlob((blob) => {
    let date = Date.now();
    const file = new File([blob], `captured_image_${date}.png`, { type: 'image/png' });
    console.log('file:::::::::::file', file); // This file object can now be uploaded to the server
    // Create a DataTransfer object and use it to set the file into the input element
    const dataTransfer = new DataTransfer();
    dataTransfer.items.add(file);
    fileInput.files = dataTransfer.files;
    // Optionally, trigger an event to handle the file upload logic if needed
    const event = new Event('change');
    fileInput.dispatchEvent(event);
    // You can also create a temporary URL to download the file
    const link = document.createElement('a');
    link.href = URL.createObjectURL(file);
    link.download = `captured_image_${date}.png`;
    link.click();
  }, 'image/png');
});
fileInput.addEventListener('change', (event) => {
  const file = event.target.files[0];
  if (file) {
    const reader = new FileReader();
    reader.onload = (e) => {
      const img = new Image();
      img.onload = () => {
        const context = canvas.getContext('2d');
        context.drawImage(img, 0, 0, canvas.width, canvas.height);
      };
      img.src = e.target.result;
    };
    reader.readAsDataURL(file);
  }
});
$("#finalUpload").on('click',function(){
  let file = $("#file-input")[0].files[0]
  console.log('upload file:::::::', file)
})

Explanation of the JavaScript Code

  1. Accessing the Webcam: Using navigator.mediaDevices.getUserMedia, the script requests access to the user's webcam. If granted, the video stream is displayed in the video element. If denied, a file input for image upload is shown instead.
  2. Capturing the Photo: When the "Capture Photo" button is clicked, the current frame from the video feed is drawn onto the canvas. The canvas content is then converted to a Blob object, which is used to create a File object. This file is programmatically set as the value of the file input element.
  3. Handling File Uploads: When a file is selected via the file input, a FileReader reads the file and draws it onto the canvas for display. This ensures that users can preview the uploaded image.
  4. Final Upload: The "Final Upload" button logs the selected file to the console, simulating the upload process.

Conclusion

This simple yet functional interface demonstrates how to integrate webcam capture and file upload capabilities into a web application. By providing both options, users are given flexibility, enhancing their experience and increasing the application's versatility. This approach can be further extended by adding server-side handling for the uploaded images, implementing additional image processing, and refining the user interface for better usability.