import { BrowserMultiFormatReader } from '@zxing/browser'; import { DecodeHintType, NotFoundException } from '@zxing/library'; import { nativeToZxingFormat, zxingToNativeFormat } from './constants'; export class BarcodeDetector { reader; constructor(options) { const hints = new Map([ [DecodeHintType.TRY_HARDER, true], [ DecodeHintType.POSSIBLE_FORMATS, options ? options.formats.map((f) => nativeToZxingFormat[f]) : Object.values(nativeToZxingFormat), ], ]); this.reader = new BrowserMultiFormatReader(hints); } static getSupportedFormats() { return Promise.resolve(Object.values(zxingToNativeFormat)); } async detect(imageSource) { try { let result; if (imageSource instanceof HTMLVideoElement || imageSource instanceof HTMLImageElement) { result = await this.reader.scanOneResult(imageSource, false); } else if (imageSource instanceof HTMLCanvasElement) { result = this.reader.decodeFromCanvas(imageSource); } else if (imageSource instanceof Blob) { const image = await this.blobToImage(imageSource); result = await this.reader.scanOneResult(image, false); } else if (imageSource instanceof ImageBitmap || imageSource instanceof ImageData || imageSource instanceof VideoFrame) { result = this.reader.decodeFromCanvas(this.imageDataSourceToCanvas(imageSource)); } else { throw new TypeError('Image source is not supported'); } return [{ rawValue: result.getText(), format: zxingToNativeFormat[result.getBarcodeFormat()], boundingBox: new DOMRectReadOnly(), // TODO: think of a way to map this in a meaningful way cornerPoints: result.getResultPoints().map((p) => ({ x: p.getX(), y: p.getY() })), }]; } catch (err) { if (err && !(err instanceof NotFoundException)) { throw err; } return []; } } async blobToImage(blob) { return new Promise((resolve, reject) => { const imageObjUrl = URL.createObjectURL(blob); const image = new Image(); image.onload = () => { URL.revokeObjectURL(imageObjUrl); resolve(image); }; image.onerror = () => reject(); image.src = imageObjUrl; }); } imageDataSourceToCanvas(source) { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); const width = source instanceof VideoFrame ? source.displayWidth : source.width; const height = source instanceof VideoFrame ? source.displayHeight : source.height; if (ctx) { if (source instanceof ImageData) { ctx.putImageData(source, width, height); } else { ctx.drawImage(source, width, height); } } return canvas; } } //# sourceMappingURL=BarcodeDetector.js.map