-
-
Notifications
You must be signed in to change notification settings - Fork 233
Open
Description
Does anybody have an solution, that would work with the latest version of the package?
Great package odahcam!
Thank you NilsEngelbach very helpful!!!.
Using your code was the only way for me to read the PDF147 with an iPhone.
Everyone else, you need to create a canvas and then play the video on the canvas before calling.
BrowserCodeReader.createBinaryBitmapFromCanvas = function (canvas: HTMLCanvasElement): BinaryBitmap.
I also had to wait for the video to load and wait for it to have a size (using setInterval and setTimeout).
Good Luck :)
I did it like this .
in HTML <canvas id="canvas" class="canvas" hidden></canvas> <zxing-scanner [torch]="torchEnabled" [device]="deviceCurrent" (deviceChange)="onDeviceChange($event)" (scanSuccess)="onCodeResult($event)" [formats]="formatsEnabled" [tryHarder]="tryHarder" (permissionResponse)="onHasPermission($event)" (camerasFound)="onCamerasFound($event)" (torchCompatible)="onTorchCompatible($event)" (scanError)="onScanError($event)" style="max-height: 60%; width: auto; object-fit: contain;"></zxing-scanner>` scss .canvas { position: absolute; top: 60px; left: 20px; height: 438px; width: 768px; } in TS ngOnInit(): void { this.loadingInterval = setInterval(() => { this.loading = this.zXingScannerComponent?.isAutostarting ?? true; if (!this.loading) { this.croppingBox() console.log('this.croppingBox()') clearInterval(this.loadingInterval); } }, 100); } onCamerasFound(devices: MediaDeviceInfo[]): void { this.availableDevices = devices; this.hasDevices = Boolean(devices && devices.length); this.zXingScannerComponent.getAnyVideoDevice = (): Promise<MediaStream> => { return navigator.mediaDevices.getUserMedia({ audio: false, video: { width: {min: 640, ideal: 1920}, height: {min: 400, ideal: 1080}, aspectRatio: {ideal: 1.7777777778} } }); }; BrowserCodeReader.prototype.decodeFromVideoDevice = async function ( deviceId: string | undefined, previewElem: string | HTMLVideoElement | undefined, callbackFn: any, ): Promise<IScannerControls> { // We had to comment this out because it is a private method... // BrowserCodeReader.checkCallbackFnOrThrow(callbackFn); let videoConstraints: MediaTrackConstraints; if (!deviceId) { videoConstraints = {facingMode: 'environment'}; } else { videoConstraints = { deviceId: {exact: deviceId}, width: {min: 640, ideal: 1920}, height: {min: 400, ideal: 1080}, aspectRatio: {ideal: 1.7777777778} }; } const constraints: MediaStreamConstraints = {video: videoConstraints}; return await this.decodeFromConstraints(constraints, previewElem, callbackFn); } } drawImage(canvas, video, width, height) { canvas.getContext('2d', {alpha: false}).drawImage(video, 0, 0, width, height); } croppingBox() { // https://github.com/zxing-js/ngx-scanner/issues/365 let squareShape = false let timeout let canvas = <HTMLCanvasElement>document.getElementById("canvas"); let video = (document.querySelector('zxing-scanner video') as any) const fps = 60; const width = 1280; const height = 720; let canvasInterval = null; canvasInterval = window.setInterval(() => { this.drawImage(canvas, video, width, height); }, 1000 / fps); video.onpause = function () { clearInterval(canvasInterval); }; video.onended = function () { clearInterval(canvasInterval); }; video.onplay = function () { clearInterval(canvasInterval); canvasInterval = window.setInterval(() => { this.drawImage(canvas, video, width, height); }, 1000 / fps); }; BrowserCodeReader.createBinaryBitmapFromCanvas = function (canvas: HTMLCanvasElement): BinaryBitmap { const cameraCanvasImageWidth = canvas.width; const cameraCanvasImageHeight = canvas.height; let videoElementHeight = (document.querySelector('zxing-scanner video') as any).offsetHeight; let videoElementWidth = (document.querySelector('zxing-scanner video') as any).offsetWidth; while (videoElementHeight < 1) { let tries = 0 timeout = setTimeout(() => { tries++ videoElementHeight = (document.querySelector('zxing-scanner video') as any).offsetHeight; videoElementWidth = (document.querySelector('zxing-scanner video') as any).offsetWidth; console.log('tries', tries) if (tries > 100) { clearTimeout(timeout) } }, 5000); } let factor = 1; if (videoElementWidth > videoElementHeight) { factor = cameraCanvasImageWidth / videoElementWidth; } else { factor = cameraCanvasImageHeight / videoElementHeight; } // console.log('factor', factor) const width = Math.floor((squareShape ? 250 : 450) * factor); const height = Math.floor((squareShape ? 250 : 200) * factor); const left = (cameraCanvasImageWidth - width) / 2; const top = (cameraCanvasImageHeight - height) / 2; const croppedCanvas = document.createElement('canvas'); croppedCanvas.width = width; croppedCanvas.height = height; const croppedCanvasContext = croppedCanvas.getContext('2d'); croppedCanvasContext.rect(0, 0, width, height); croppedCanvasContext.fillStyle = 'red'; croppedCanvasContext.fill(); console.log('drawImage', canvas, left, top, width, height) croppedCanvasContext.drawImage(canvas, left, top, width, height, 0, 0, width, height); // These lines can be used to show the cropped part of the image stream that is used // to find the code and check if the highlighted area matches the cropped image // document.getElementById('croppedSvg').innerHTML = ''; // const span = document.createElement('span'); // span.textContent = `${cameraCanvasImageWidth} x ${cameraCanvasImageHeight} | ${videoElementWidth} x ${videoElementHeight}`; // span.style.position = 'absolute'; // span.style.right = `0`; // span.style.color = 'black'; // span.style.display = 'block'; // document.getElementById('croppedSvg').appendChild(span); // croppedCanvas.style.marginTop = '20px'; // croppedCanvas.style.transform = `scale(1)`; // croppedCanvas.style.transformOrigin = `right top`; // document.getElementById('croppedSvg').appendChild(croppedCanvas); let luminanceSource = new HTMLCanvasElementLuminanceSource(croppedCanvas); // .invert() to support inverted codes const hybridBinarizer = new HybridBinarizer(luminanceSource); return new BinaryBitmap(hybridBinarizer); }; }
Metadata
Metadata
Assignees
Labels
No labels