web-apis 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 7 months ago