Barcode Detection API - Parte 2 Usando a câmera para detectar código
Desta vez usaremos TypeScript e para que isso seja feito sem alertas de erro no código, precisaremos que a API esteja devidamente tipada, porém, não temos disponível no arquivo lib.dom.ts
do TypeScript . Eu mesmo escrevi um seguindo a especificação, vai servir por enquanto.
barcode.d.ts
Crie um arquivo barcode.d.ts com o conteúdo a seguir.
Copy interface BarcodeDetector {
new (barcodeDetectorOptions ?: BarcodeDetectorOptions ) : BarcodeDetector ;
static getSupportedFormats () : Promise < BarcodeFormat []>;
detect (image : ImageBitmapSource ) : Promise < DetectedBarcode []>;
}
declare var BarcodeDetector : {
prototype : BarcodeDetector ;
new (barcodeDetectorOptions ?: BarcodeDetectorOptions ) : BarcodeDetector ;
};
interface BarcodeDetectorOptions {
formats : BarcodeFormat ;
}
interface Point2D {
x : number
y : number
}
interface DetectedBarcode {
boundingBox : DOMRectReadOnly ;
rawValue : string ;
format : BarcodeFormat ;
cornerPoints : Point2D [];
}
type BarcodeFormat =
| "aztec"
| "code_128"
| "code_39"
| "code_93"
| "codabar"
| "data_matrix"
| "ean_13"
| "ean_8"
| "itf"
| "pdf417"
| "qr_code"
| "unknown"
| "upc_a"
| "upc_e" ;
Agora sim, partimos para implementação.
Basicamente o que precisamos fazer é:
Capturar o stream
de vídeo do dispositivo
Desenhar o video
em um elemento canvas
Executar o método de detecção no canvas
Se houver resultados, desenhar no canvas
Vamos lá!
main.ts
Copy const stream$ = navigator . mediaDevices .getUserMedia ({
video : {facingMode : 'environment' } ,
})
const detector = new BarcodeDetector ()
const value = new Text ()
const h1 = document .createElement ( 'h1' )
h1 .append (value)
const video = document .createElement ( 'video' )
video .autoplay = true
const canvas = document .createElement ( 'canvas' )
canvas .width = 640
canvas .height = 480
document . body .append (canvas , h1)
const context = canvas .getContext ( '2d' )
if ( ! context) throw `context error`
Vamos separar a função draw
draw.ts
Copy export function draw (
context : CanvasRenderingContext2D ,
paths : Point2D [] ,
color = 'lime' ,
width = 3
) {
const [ topLeft , topRight , bottomRight , bottomLeft ] = paths
context .strokeStyle = color
context .lineWidth = width
context .beginPath ()
context .moveTo ( topLeft .x , topLeft .y)
context .lineTo ( topRight .x , topRight .y)
context .lineTo ( bottomRight .x , bottomRight .y)
context .lineTo ( bottomLeft .x , bottomLeft .y)
context .closePath ()
context .stroke ()
}
De volta ao main.ts
, vamos finalizar!
Copy // ...
stream$ .then ((stream) => {
video .srcObject = stream
video . ontimeupdate = async () => {
context .drawImage (video , 0 , 0 , 640 , 480 )
const result = await detector .detect (canvas)
if ( result . length > 0 ) {
for ( const detected of result) {
draw (context , detected .cornerPoints)
value .textContent = detected .rawValue
}
}
}
})
E então, o que achou? Espero que tenha gostado!
Abraço
Last updated 4 months ago