From 6d688ef88d26a520812afca7c9b6c5fd0c49a5b1 Mon Sep 17 00:00:00 2001 From: kj1352 Date: Mon, 8 Feb 2021 12:13:43 +0530 Subject: [PATCH] Capture image from AR --- package-lock.json | 34 ++++++++++++ package.json | 8 +++ src/app/ar-fan-cam/ar-fan-cam.page.html | 22 ++++++-- src/app/ar-fan-cam/ar-fan-cam.page.scss | 71 +++++++++++++++++++++++-- src/app/ar-fan-cam/ar-fan-cam.page.ts | 55 +++++++++++++++---- src/app/fan-zone/fan-zone.page.ts | 11 +++- 6 files changed, 181 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index 79ee953..ecc4087 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2343,6 +2343,12 @@ "resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz", "integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ=" }, + "@types/dom-mediacapture-record": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/dom-mediacapture-record/-/dom-mediacapture-record-1.0.7.tgz", + "integrity": "sha512-ddDIRTO1ajtbxaNo2o7fPJggpN54PZf1ZUJKOjto2ENMJE/9GKUvaw3ZRuQzlS/p0E+PnIcssxfoqYJ4yiXSBw==", + "dev": true + }, "@types/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", @@ -4909,6 +4915,21 @@ "timsort": "^0.3.0" } }, + "css-line-break": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-1.1.1.tgz", + "integrity": "sha512-1feNVaM4Fyzdj4mKPIQNL2n70MmuYzAXZ1aytlROFX1JsOo070OsugwGjj7nl6jnDJWHDM8zRZswkmeYVWZJQA==", + "requires": { + "base64-arraybuffer": "^0.2.0" + }, + "dependencies": { + "base64-arraybuffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz", + "integrity": "sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==" + } + } + }, "css-loader": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.5.3.tgz", @@ -5556,6 +5577,11 @@ "resolved": "https://registry.npmjs.org/dom-storage/-/dom-storage-2.1.0.tgz", "integrity": "sha512-g6RpyWXzl0RR6OTElHKBl7nwnK87GUyZMYC7JWsB/IA73vpqK2K6LT39x4VepLxlSsWBFrPVLnsSR5Jyty0+2Q==" }, + "dom-to-image": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/dom-to-image/-/dom-to-image-2.6.0.tgz", + "integrity": "sha1-ilA2CAiMh7HCL5A0rgMuGJiVWGc=" + }, "domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", @@ -7207,6 +7233,14 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "html2canvas": { + "version": "1.0.0-rc.7", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.0.0-rc.7.tgz", + "integrity": "sha512-yvPNZGejB2KOyKleZspjK/NruXVQuowu8NnV2HYG7gW7ytzl+umffbtUI62v2dCHQLDdsK6HIDtyJZ0W3neerA==", + "requires": { + "css-line-break": "1.1.1" + } + }, "htmlparser2": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", diff --git a/package.json b/package.json index ec758f0..28ae5f2 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,11 @@ "lint": "ng lint", "e2e": "ng e2e" }, + "browser": { + "fs": false, + "os": false, + "path": false + }, "private": true, "dependencies": { "@angular/common": "~10.0.0", @@ -28,10 +33,12 @@ "@ionic-native/status-bar": "^5.0.0", "@ionic/angular": "^5.0.0", "cordova-res": "^0.15.2", + "dom-to-image": "^2.6.0", "face-api.js": "^0.22.2", "faker": "^5.1.0", "firebase": "^8.2.6", "hammerjs": "^2.0.8", + "html2canvas": "^1.0.0-rc.7", "moment": "^2.29.1", "rxjs": "~6.5.5", "sharp": "^0.27.0", @@ -47,6 +54,7 @@ "@angular/compiler-cli": "~10.0.0", "@angular/language-service": "~10.0.0", "@ionic/angular-toolkit": "^2.3.0", + "@types/dom-mediacapture-record": "^1.0.7", "@types/jasmine": "~3.5.0", "@types/jasminewd2": "~2.0.3", "@types/node": "^12.11.1", 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 35185c8..385649e 100644 --- a/src/app/ar-fan-cam/ar-fan-cam.page.html +++ b/src/app/ar-fan-cam/ar-fan-cam.page.html @@ -1,9 +1,21 @@ -
+ + + +
- - - - } + +
+ + + +
+ + + + + +
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 85dd881..5a46b9a 100644 --- a/src/app/ar-fan-cam/ar-fan-cam.page.scss +++ b/src/app/ar-fan-cam/ar-fan-cam.page.scss @@ -1,5 +1,32 @@ @import '../colors'; +.test-img { + position: fixed; + z-index: 1; + left: 50%; + top: 50%; +} + +.back-button { + position: fixed; + top: 10px; + right: 10px; + width: 40px; + height: 40px; + background: rgba(white, 0.5); + border: 0px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + z-index: 3; + + ion-icon { + color: white; + font-size: 20px; + } +} + .container { position: relative; } @@ -13,11 +40,6 @@ #playback-video, #result-canvas, #three-container { display: block; - width: 100vw; - height: 75vw; - - max-width: 600px; - max-height: 450px; } #result-canvas, #three-container { @@ -39,4 +61,43 @@ .right-eye { background-color: red; +} + + +.action-buttons { + position: fixed; + left: 0; + bottom: 20px; + display: flex; + align-items: center; + width: 100%; + + button { + width: 50px; + height: 50px; + background-color: white; + color: $pink; + border-radius: 50%; + + ion-icon { + font-size: 25px; + } + + &.camera-button { + margin-left: calc(50% - 25px); + transform: scale(1.5); + } + + &.skin-button { + transform: scale(1.2); + margin-left: 40px; + background-color: transparent; + border: 2px solid $pink; + + &.active { + background-color: $pink; + color: white; + } + } + } } \ No newline at end of file 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 798e90a..2df503c 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,7 @@ import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { detectSingleFace, loadFaceExpressionModel, loadFaceLandmarkModel, loadFaceLandmarkTinyModel, loadFaceRecognitionModel, loadSsdMobilenetv1Model, loadTinyFaceDetectorModel, TinyFaceDetectorOptions } from 'face-api.js'; +import domtoimage from 'dom-to-image'; +import { Location } from '@angular/common'; @Component({ selector: 'app-ar-fan-cam', @@ -8,6 +10,7 @@ import { detectSingleFace, loadFaceExpressionModel, loadFaceLandmarkModel, loadF }) export class ArFanCamPage implements OnInit { @ViewChild('videoElement', null) videoElement: ElementRef; + mediaStream: MediaStream|null = null; glassProperties: { @@ -22,7 +25,14 @@ export class ArFanCamPage implements OnInit { width = 360; height = 270; - constructor() { } + temp: any; + + + stream: any; + + constructor( + private location: Location + ) { } loadNeuralNetModels = async () => { await loadTinyFaceDetectorModel('/assets/weights'); @@ -37,25 +47,47 @@ export class ArFanCamPage implements OnInit { this.areNeuralNetsLoaded = true; } + back() { + this.location.back(); + this.stopCameraStream(); + } + getCameraStream = async () => { const stream = await window.navigator.mediaDevices.getUserMedia({ video: { facingMode: 'user', width: this.width, + height: this.height }, - }); - - this.mediaStream = stream; - this.videoElement.nativeElement.srcObject = stream; + }).then((stream) => { + this.mediaStream = stream; + this.videoElement.nativeElement.srcObject = stream; + }).catch(err => alert(JSON.stringify(err))); }; stopCameraStream = async () => { if (this.mediaStream) { - this.mediaStream.getVideoTracks().forEach(track => track.stop()); + this.mediaStream.getVideoTracks().forEach(track => { + track.stop(); + }); + this.mediaStream = null; + this.stream = null; } } + async capture() { + let element: HTMLElement = document.querySelector('#container'); + + await domtoimage.toPng(element).then((dataUrl) => { + this.temp = dataUrl; + console.log(dataUrl); + }) + .catch((error) => { + console.error('oops, something went wrong!', error); + }); + } + detectAndDrawFace = async () => { const tinyFaceDetectorOptions = new TinyFaceDetectorOptions(); @@ -87,14 +119,19 @@ export class ArFanCamPage implements OnInit { } } - ngOnInit() { + ngOnInit() { + } + + ngAfterViewInit() { this.loadNeuralNetModels(); - const feedWidth = window.innerWidth > 600 ? 600 : window.innerWidth; - const feedHeight = feedWidth * 0.75; + const feedWidth = window.innerWidth; + const feedHeight = window.innerHeight; this.width = feedWidth; this.height = feedHeight; + + this.getCameraStream().then(() => this.detectAndDrawFace(), (err) => console.log(err)); } } diff --git a/src/app/fan-zone/fan-zone.page.ts b/src/app/fan-zone/fan-zone.page.ts index a232f4b..7381791 100644 --- a/src/app/fan-zone/fan-zone.page.ts +++ b/src/app/fan-zone/fan-zone.page.ts @@ -87,7 +87,13 @@ export class FanZonePage implements OnInit { } ngAfterViewInit() { - this.showSocialLogin = true; + if (localStorage.googleUserData) { + this.googleUserData = JSON.parse(localStorage.googleUserData); + this.showSocialLogin = false; + } else { + this.googleUserData = {}; + this.showSocialLogin = true; + } } generateEmojiStream() { @@ -153,6 +159,9 @@ export class FanZonePage implements OnInit { profileImage: data.user.photoURL, credentials: data.credential }; + + localStorage.googleUserData = JSON.stringify(this.googleUserData); + this.showSocialLogin = false; }).catch(err => { alert(err.message);