diff --git a/package-lock.json b/package-lock.json
index 351a708..f18f124 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24819,6 +24819,8 @@
"integrity": "sha512-cOyGQgMdhnRYtW2xrJUNrNYDjEgwQ+BrE2y93Bwz3h4DJ6vJRLfupemU5N3pbYsUlBHJf0u1j1UGk+NLW4d97g==",
"dev": true,
"requires": {
+ "@angular/compiler": "9.0.0",
+ "@angular/core": "9.0.0",
"app-root-path": "^3.0.0",
"aria-query": "^3.0.0",
"axobject-query": "2.0.2",
diff --git a/src/app/ar-fan-cam/ar-fan-cam.page.html b/src/app/ar-fan-cam/ar-fan-cam.page.html
index 3c0dcea..ef2d27b 100644
--- a/src/app/ar-fan-cam/ar-fan-cam.page.html
+++ b/src/app/ar-fan-cam/ar-fan-cam.page.html
@@ -5,6 +5,7 @@
+
diff --git a/src/app/ar-fan-cam/ar-fan-cam.page.scss b/src/app/ar-fan-cam/ar-fan-cam.page.scss
index 940e0d1..a27cd10 100644
--- a/src/app/ar-fan-cam/ar-fan-cam.page.scss
+++ b/src/app/ar-fan-cam/ar-fan-cam.page.scss
@@ -58,7 +58,7 @@
display: block;
}
-#result-canvas, #source-canvas, #three-container {
+#result-canvas, #source-canvas, #source-image, #three-container {
position: absolute;
top: 0;
left: 0;
diff --git a/src/app/ar-fan-cam/ar-fan-cam.page.ts b/src/app/ar-fan-cam/ar-fan-cam.page.ts
index f466518..b1a46a6 100644
--- a/src/app/ar-fan-cam/ar-fan-cam.page.ts
+++ b/src/app/ar-fan-cam/ar-fan-cam.page.ts
@@ -1,5 +1,6 @@
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { detectSingleFace, loadFaceExpressionModel, loadFaceLandmarkModel, loadFaceLandmarkTinyModel, loadFaceRecognitionModel, loadSsdMobilenetv1Model, loadTinyFaceDetectorModel, TinyFaceDetectorOptions } from 'face-api.js';
+import { CameraPreview, CameraPreviewPictureOptions, CameraPreviewOptions, CameraPreviewDimensions } from '@ionic-native/camera-preview/ngx';
import { Location } from '@angular/common';
import { ModalController } from '@ionic/angular';
@@ -12,6 +13,7 @@ export class ArFanCamPage implements OnInit {
@ViewChild('videoElement') videoElement: ElementRef;
@ViewChild('glassesElement') glassesElement: ElementRef;
@ViewChild('canvasElement') canvasElement: ElementRef;
+ @ViewChild('sourceImageElement') sourceImageElement: ElementRef;
@ViewChild('sourceCanvasElement') sourceCanvasElement: ElementRef;
mediaStream: MediaStream|null = null;
@@ -34,8 +36,20 @@ export class ArFanCamPage implements OnInit {
constructor(
private location: Location,
- private modalController: ModalController
- ) { }
+ private modalController: ModalController,
+ private cameraPreview: CameraPreview
+ ) {
+ this.sourceImageElement.nativeElement.onload = () => {
+ const context = this.sourceCanvasElement.nativeElement.getContext('2d');
+ context.drawImage(
+ this.sourceImageElement.nativeElement,
+ 0,
+ 0,
+ this.sourceCanvasElement.nativeElement.width,
+ this.sourceCanvasElement.nativeElement.height
+ );
+ }
+ }
loadNeuralNetModels = async () => {
await loadTinyFaceDetectorModel('/assets/weights');
@@ -56,19 +70,38 @@ export class ArFanCamPage implements OnInit {
}
getCameraStream = async () => {
- const stream = await window.navigator.mediaDevices.getUserMedia({
- video: {
- facingMode: 'user',
- width: this.width,
- height: this.height
- },
- }).then((stream) => {
- this.mediaStream = stream;
- this.videoElement.nativeElement.srcObject = stream;
- }).catch(err => alert(JSON.stringify(err)));
+ if (this.cameraPreview) {
+ const cameraPreviewOpts: CameraPreviewOptions = {
+ x: 0,
+ y: 0,
+ width: window.screen.width,
+ height: window.screen.height,
+ camera: 'rear',
+ tapPhoto: true,
+ previewDrag: true,
+ toBack: true,
+ alpha: 1
+ }
+ this.cameraPreview.startCamera(cameraPreviewOpts);
+ } else {
+ const stream = await window.navigator.mediaDevices.getUserMedia({
+ video: {
+ facingMode: 'user',
+ width: this.width,
+ height: this.height
+ },
+ }).then((stream) => {
+ this.mediaStream = stream;
+ this.videoElement.nativeElement.srcObject = stream;
+ }).catch(err => alert(JSON.stringify(err)));
+ }
};
stopCameraStream = async () => {
+ if (this.cameraPreview) {
+ this.cameraPreview.stopCamera();
+ }
+
if (this.mediaStream) {
this.mediaStream.getVideoTracks().forEach(track => {
track.stop();
@@ -116,12 +149,25 @@ export class ArFanCamPage implements OnInit {
context.clearRect(0, 0, window.innerWidth, window.innerHeight);
}
- detectAndDrawFace = async () => {
- const tinyFaceDetectorOptions = new TinyFaceDetectorOptions();
+ async getSnapshotFromPreview() {
+ const base64Image: string = await this.cameraPreview.takeSnapshot();
+ this.sourceImageElement.nativeElement.src = base64Image;
+ }
+ getSnapshotFromVideo() {
const sourceCanvas = this.sourceCanvasElement.nativeElement;
const context = sourceCanvas.getContext('2d');
context.drawImage(this.videoElement.nativeElement, 0, 0, sourceCanvas.width, sourceCanvas.height);
+ }
+
+ detectAndDrawFace = async () => {
+ const tinyFaceDetectorOptions = new TinyFaceDetectorOptions();
+
+ if (this.cameraPreview) {
+ await this.getSnapshotFromPreview();
+ } else {
+ this.getSnapshotFromVideo();
+ }
let detectionWithLandmarks = await detectSingleFace(this.sourceCanvasElement.nativeElement, tinyFaceDetectorOptions).withFaceLandmarks(true);