Today we are going to learn how to use a webcam in angular 13.
Some time ago, I was curious to know about how to capture camera images in angular because I was working on a project where I needed this feature.
So, today we are going to use ngx-webcam
which is a node package to solve this problem.
Actually we will discuss two methods to use webcam in angular.
ngx-webcam
packageWe will achieve the following goals
I am assuming that you already have an angular project, so, I won’t explain the angular installation process here.
I am using the same angular project, which I have created in the previous tutorial.
Before starting, let’s install the required packages.
npm install file-saver --save
# Additional typescript definitions npm install @types/file-saver --save-dev
npm i ngx-webcam
Import the ngx-webcam
module to the required module file, In my case it is form.module.ts but you can import to the app.module.ts
also. I am using webcam in the form.component.ts
so, I am importing it to form.module.ts
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormComponent } from './form.component'; import { FormRoutingModule } from './form-routing.module'; import { SharedModule } from '../shared.module'; import { ReactiveFormsModule } from '@angular/forms'; import {MatFormFieldModule} from '@angular/material/form-field'; import {MatSelectModule} from '@angular/material/select'; import { WebcamModule } from 'ngx-webcam'; @NgModule({ declarations: [ FormComponent ], imports: [ CommonModule, FormRoutingModule, ReactiveFormsModule, MatFormFieldModule, MatSelectModule, SharedModule, WebcamModule ] }) export class FormModule { }
Let’s create an angular service in this project called fileService
to handle image file related tasks like to convert file uri to blob and save to directory.
import { Injectable } from "@angular/core"; import * as FileSaver from "file-saver"; import { Observable, Observer } from "rxjs"; @Injectable({ providedIn: 'root' }) export class FileService { createBlobImageFileAndSave(base64ImageUrl: string, ext: string = 'jpeg'): void { //console.log({base64ImageUrl}) this.dataURItoBlob(base64ImageUrl, ext).subscribe((blob: Blob) => { const imageBlob: Blob = blob; const imageName: string = this.generateName(ext); FileSaver.saveAs(imageBlob, imageName); }); } /* Method to convert Base64Data Url as Image Blob */ dataURItoBlob(dataURI: string, ext: string): Observable<Blob> { return new Observable((observer: Observer<Blob>) => { const byteString: string = window.atob(dataURI); const arrayBuffer: ArrayBuffer = new ArrayBuffer(byteString.length); const int8Array: Uint8Array = new Uint8Array(arrayBuffer); for (let i = 0; i < byteString.length; i++) { int8Array[i] = byteString.charCodeAt(i); } const blob = new Blob([int8Array], { type: `image/${ext}` }); observer.next(blob); observer.complete(); }); } /**Method to Generate a Name for the Image */ generateName(ext: string): string { const date: number = new Date().valueOf(); let text: string = ""; const possibleText: string = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (let i = 0; i < 5; i++) { text += possibleText.charAt( Math.floor(Math.random() * possibleText.length) ); } // Replace extension according to your media type like this return date + "." + text + "." + ext; } }
In this service file, we have three methods generateName
is to generate a random name for the image file. Second is dataURItoBlob
, this method will help us to convert our file uri to blob objects. Third method is createBlobImageFileAndSave
this is the entry point, it is responsible to create blob file, file name by using first and second method and at the end save the file to the local directory by using fileSaver
package.
I have an angular component called show.component.ts
with below code.
show.component.ts
import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { FileService } from '../file.service'; import { UserService } from '../user.service'; @Component({ selector: 'app-show', templateUrl: './show.component.html', styleUrls: ['./show.component.scss'], changeDetection: ChangeDetectionStrategy.Default }) export class ShowComponent implements OnInit, AfterViewInit { @ViewChild("video") public video: ElementRef; @ViewChild("canvas") public canvas: ElementRef; public images: Array<any>; constructor( private fileService: FileService ) { this.images = []; } ngOnInit(): void { } public ngAfterViewInit() { if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { navigator.mediaDevices.getUserMedia({ video: true }).then(stream => { this.video.nativeElement.srcObject = stream; this.video.nativeElement.play(); }); } } public takePicture() { this.canvas.nativeElement.getContext("2d").drawImage(this.video.nativeElement, 0, 0, 512, 512); this.images.push(this.canvas.nativeElement.toDataURL("image/png")); } public savePicture() { this.takePicture(); if (this.images.length > 0) { let image_data = this.images[this.images.length-1].split('base64,'); this.fileService.createBlobImageFileAndSave(image_data[1], 'png'); } } }
In the above angular component, you can see that I am using file service. Other than that I am using a video html element to interact with the user webcam and canvas html element to draw the captured image.
After this process I am storing the pictures in the images
array to preview on the html page.
show.component.html
<div> <div> <video #video id="video" width="512" height="512" autoplay></video> </div> <div> <button class="btn btn-primary" (click)="takePicture()">Take Picture</button> <button class="btn btn-primary" (click)="savePicture()">Save Picture</button> </div> <canvas #canvas id="canvas" width="512" height="512"></canvas> <ul> <li *ngFor="let src of images"> <img src="{{ src }}" height="50" /> </li> </ul> </div>
Once I get the picture from the webcam, I am calling the file service methods to convert that base64 picture data to an image file and store it in the directory.
As we have already installed the ngx-webcam
package. Let’s go to another angular component that is form.component.ts
.
form.component.ts
import { Component, EventEmitter, OnInit, Output } from '@angular/core'; import { WebcamImage, WebcamInitError } from 'ngx-webcam'; import { Observable, Subject } from 'rxjs'; import { FileService } from '../file.service'; @Component({ selector: 'app-form', templateUrl: './form.component.html', styleUrls: ['./form.component.scss'] }) export class FormComponent implements OnInit { images: Array<any> = []; @Output() public imageClicked = new EventEmitter<WebcamImage>(); public errors: WebcamInitError[] = []; private cameraClick: Subject<void> = new Subject<void>(); constructor( private fileService: FileService ) { } ngOnInit(): void { } public takePicture(): void { this.cameraClick.next(); } public errorHandler(error: WebcamInitError): void { this.errors.push(error); } public pictureHandler(webcamImage: WebcamImage): void { this.images.push(webcamImage.imageAsDataUrl); this.imageClicked.emit(webcamImage); } public saveImage() { this.takePicture(); if (this.images.length > 0) { let image_data = this.images[this.images.length-1].split('base64,'); this.fileService.createBlobImageFileAndSave(image_data[1]); } } public get clickOnCamera(): Observable<void> { return this.cameraClick.asObservable(); } }
Almost the same process here in the form.component.ts
as in the show.component.ts
with native mediaSteam API. But in this component we are using the ngx-webcam
package. This package provides us with the webcam component which we are using in the form.component.html
template.
The beauty of the webcam component is that we can pass all the required options to it like trigger to click the picture, image handler, error handler etc.
So, we have full control here with minimum effort.
form.component.html
<div class="d-flex flex-column align-items-center"> <webcam [height]="512" [width]="512" [trigger]="clickOnCamera" (imageCapture)="pictureHandler($event)" (initError)="errorHandler($event)"></webcam> <button class="btn btn-primary" (click)="takePicture();" title="Take Picture">Take Picture</button> <button class="btn btn-warning" (click)="saveImage();" title="Save Picture">Save Picture</button> </div> <ul> <li *ngFor="let src of images"> <img src="{{ src }}" height="50" /> </li> </ul> <h4 *ngIf="errors.length > 0">Messages:</h4> <ul *ngFor="let error of errors"> <li>{{error | json}}</li> </ul>
That’s all, how to use webcam in angular 13 shown with two methods one is native HTML and mediaStream API and second is ngx-webcam
node package.
Today we are going to learn about managing multiple PHP versions on ubuntu with xampp.…
Let's understand about how to use coding to improve your website's SEO. In today’s computerized…
Let's understand the most important linux commands for web developers. Linux, as an open-source and…
Today we are going to discuss top 75+ Laravel interview questions asked by top MNCs.Laravel,…
Today we will discuss about the Mailtrap integration with laravel 10 .Sending and receiving emails…
Today we are going to integrate FCM (Firebase Cloud Messaging) push notifications with ionic application.Firebase…