Publicado el 09.07.2022 a las 11:59
La aplicación que vamos a crear no sólo leerá códigos QR, sino que también podrá leer código de barra de toda la vida.
Crearemos el core de la aplicación, será funcional pero no será muy bonita. Ya te encargas tú de darle estilo 😁
Tendrá un desplegable en donde podremos seleccionar que cámara del dispositivo usar y cada 200 ms leeremos la pantalla en busca de algún código, si encontramos alguno válido lo imprimimos en consola y en el HMTL como un párrafo.
Así será 👇
No es la aplicación más bonita del mundo pero funciona.
Puedes descargar o clonar este proyecto desde mi GitHub 👈🚀
Nos vamos a apoyar en una librería que nos va a hacer la vida más fácil, dicha librería es ngx-scanner.
Actualmente tiene más de 20.000 descargar semanales, te dejo aquí el link al repositorio de npm.
La librería es fácil de usar, pero me pegué 2 horas intentando seleccionar la cámara web de mi portátil y por eso me decidí a escribir este artículo.
La versión válida de la librería para Angular 13 es la 3.5.0
Para seleccionar los medios de captura de imagen de tu dispositivo de forma nativa usando la api del navegador 👇
navigator.mediaDevices.enumerateDevices().then((devices) => { for (var i = 0; i < devices.length; i++) { var device = devices[i]; if (device.kind === 'videoinput') { console.log(device); this.myDevice = devices[1]; } } console.log(this.myDevice); });
No obstante la librería ya te facilita el método camerasFound
Te dejo todas las propiedades y métodos que puedes usar con la librería
<zxing-scanner [enable]="scannerEnabled" [(device)]="desiredDevice" [torch]="torch" (torchCompatible)="onTorchCompatible($event)" (camerasFound)="camerasFoundHandler($event)" (camerasNotFound)="camerasNotFoundHandler($event)" (scanSuccess)="scanSuccessHandler($event)" (scanError)="scanErrorHandler($event)" (scanFailure)="scanFailureHandler($event)" (scanComplete)="scanCompleteHandler($event)" ></zxing-scanner>
Parámetro | Default | Descripción |
---|---|---|
enable | true | Activa/desactiva el escaneo de la cámara en busca de códigos. |
device | Será la cámara que se usará para escanear los código. | |
torch (experimental) | Podremos activar/desactivar el flash de la cámara | |
torchCompatible (experimental) | Nos dirá si el flash es compatible con la cámara. | |
camerasFound | Evento que emite un array de cámaras de tu dispositivo después de que la aplicación haya iniciado. | |
camerasNotFound | Evento emitido cuando no se encuentran cámaras en tu dispositivo. | |
scanSuccess | Evento que emite la cadena de texto detrás del código leído por la cámara. | |
scanError | Evento emitido por un error durante la lectura de la cámara. | |
scanFailure | Evento emitido cuando no se puede leer el código por la cámara. | |
scanComplete | Evento emitido tras el escaneo de un código, independientemente de si el escaneo es satisfactorio o no. |
<select #selectList (change)="selectCamera(selectList.value)"> <option *ngFor="let camera of cameras" value={{camera.label}}> {{ camera.label }} </option> </select> <zxing-scanner style="width: 500px;" [enable]="scannerEnabled" [device]="myDevice" (camerasFound)="camerasFoundHandler($event)" (scanSuccess)="scanSuccessHandler($event)" ></zxing-scanner> <p *ngFor="let result of results">{{result}}</p>
import { Component, inject } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], }) export class AppComponent { title = 'qr-reader'; public cameras:MediaDeviceInfo[]=[]; public myDevice!: MediaDeviceInfo; public scannerEnabled=false; public results:string[]=[]; constructor() { } camerasFoundHandler(cameras: MediaDeviceInfo[]){ this.cameras=cameras; this.selectCamera(this.cameras[0].label); } scanSuccessHandler(event:string){ console.log(event); this.results.unshift(event); } selectCamera(cameraLabel: string){ this.cameras.forEach(camera=>{ if(camera.label.includes(cameraLabel)){ this.myDevice=camera; console.log(camera.label); this.scannerEnabled=true; } }) } }
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { ZXingScannerModule } from '@zxing/ngx-scanner'; import { AppComponent } from './app.component'; @NgModule({ declarations: [AppComponent], imports: [BrowserModule, ZXingScannerModule], providers: [], bootstrap: [AppComponent], }) export class AppModule {}
Como ya te he dicho, lo tienes todo en mi GitHub 👈🚀
Hasta luego 🖖