我正在尝试构建一个Ionic应用程序,该应用程序使用“ getUserMedia”获取手机的后置摄像头并将此视频绘制到画布中。然后,应该在画布中使用名为jsQR的库识别QR码。
我尝试了多种创建画布的方法,以此类推,突然间我意识到,在chrome浏览器中,使用“离子服务”将应用程序完美部署就可以了。
我的问题是,如果我运行“ ionic cordova run android”,它将无法按需绘制到画布中。 可视化: https://imgur.com/a/A6zVneK
在chrome中的外观: https://imgur.com/a/cSLtAdJ
我的HTML:
<ion-header>
<meta charset="utf-8">
<title>jsQR Demo</title>
<link href="https://fonts.googleapis.com/css?family=Ropa+Sans" rel="stylesheet">
</ion-header>
<ion-content>
<h1 style="text-align: center">Jack's QR with User Media Test</h1>
<div #videoContainer></div>
<div #canvasContainer>
</div>
</ion-content>
我的TYPESCRIPT:
import {AfterViewInit, Component, ViewChild} from '@angular/core';
import jsQR from 'jsqr';
import { Platform } from '@ionic/angular';
import { AndroidPermissions } from '@ionic-native/android-permissions/ngx';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage implements AfterViewInit {
@ViewChild('videoContainer') videoContainer;
public video: HTMLVideoElement;
@ViewChild('canvasContainer') canvasContainer;
public canvas: HTMLCanvasElement;
public canvasContext: CanvasRenderingContext2D;
constructor(private platform: Platform, private androidPermissions: AndroidPermissions) {
this.video = document.createElement('video');
this.video.width = 640;
this.video.height = 480;
this.video.setAttribute('autoplay', '');
this.video.setAttribute('playsinline', '');
this.video.setAttribute('facingMode', 'environment');
this.video.setAttribute('hidden', '');
this.canvas = document.createElement('canvas');
this.canvas.width = 640;
this.canvas.height = 480;
this.canvasContext = this.canvas.getContext('2d');
if (this.platform.is('cordova')) {
this.platform.ready().then(() => {
this.androidPermissions.checkPermission(this.androidPermissions.PERMISSION.CAMERA).then(
result => console.log('Has permission?', result.hasPermission),
err => this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.CAMERA)
);
this.androidPermissions.requestPermissions([this.androidPermissions.PERMISSION.CAMERA]).then(() => {});
});
}
}
ngAfterViewInit() {
this.videoContainer.nativeElement.appendChild(this.video);
this.canvasContainer.nativeElement.appendChild(this.canvas);
this.initWebRTC();
}
initWebRTC() {
const constraints = {
video: true,
audio: false,
facingMode: 'environment'
};
const handleSuccess = (stream: MediaStream) => {
this.video.srcObject = stream;
this.video.setAttribute('playsinline', '');
this.video.play();
requestAnimationFrame(() => {
this.draw();
});
};
navigator.mediaDevices.getUserMedia(constraints).then(handleSuccess);
}
drawLine(begin, end) {
this.canvasContext.beginPath();
this.canvasContext.moveTo(begin.x, begin.y);
this.canvasContext.lineTo(end.x, end.y);
this.canvasContext.lineWidth = 4;
this.canvasContext.strokeStyle = '#4139ff';
this.canvasContext.stroke();
}
draw() {
this.canvas.height = this.video.height;
this.canvas.width = this.video.width;
this.canvasContext.drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);
const imageData = this.canvasContext.getImageData(0, 0, this.canvas.width, this.canvas.height);
const code = jsQR(imageData.data, imageData.width, imageData.height, { inversionAttempts: 'dontInvert' });
if (code) {
console.log('I found a QR!');
this.drawLine(code.location.topLeftCorner, code.location.topRightCorner);
this.drawLine(code.location.topRightCorner, code.location.bottomRightCorner);
this.drawLine(code.location.bottomRightCorner, code.location.bottomLeftCorner);
this.drawLine(code.location.bottomLeftCorner, code.location.topLeftCorner);
}
requestAnimationFrame(() => {
this.draw();
});
}
}
我的问题还在于:在手机上运行的Ionic应用程序与在计算机上运行的“浏览器”不同,例如铬?