accurafaceplugin 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- export default class FacePlugin{constructor(e,t){this.haarcascadeUrl=e,this.faceDetectionCount=0,this.onResultReceived=t,this.FPS=30,this.ZOOM_FACTOR=1.5,this.lastFaceDetectionTime=Date.now(),this.opencvLoaded=!1,this.createUI(),this.addStyles(),this.video=document.getElementById("videoInput"),this.canvas=document.getElementById("canvasOutput"),this.instructionText=document.getElementById("instructionText"),this.loader=document.getElementById("loader");const n=document.createElement("script");n.src="https://cdn.jsdelivr.net/npm/piexifjs@1.0.6/piexif.min.js",document.head.appendChild(n),this.checkOpenCV()}createUI(){const e=document.createElement("div");e.className="container";const t=document.createElement("div");t.className="camera-input",t.style.position="relative";const video=document.createElement("video");video.id="videoInput",video.width=640,video.height=480,video.autoplay=!0,video.muted=!0;const canvas=document.createElement("canvas");canvas.id="canvasOutput",canvas.style.display="none";const n=document.createElement("div");n.id="loader",n.className="loader",n.style.display="none";const i=document.createElement("p");i.id="instructionText",t.appendChild(video),t.appendChild(canvas),t.appendChild(n),e.appendChild(t),e.appendChild(i),document.body.appendChild(e)}checkOpenCV(){const e=()=>{window.cv?(this.opencvLoaded=!0,this.openCvReady()):setTimeout(e,100)};e()}openCvReady(){navigator.mediaDevices.getUserMedia({video:!0,audio:!1}).then((e=>{this.video.srcObject=e,this.video.play(),this.isCanvasVisible=!1,this.video.addEventListener("loadedmetadata",(()=>{if(this.video.videoWidth&&this.video.videoHeight){this.video.width=this.video.videoWidth,this.video.height=this.video.videoHeight,this.canvas.width=this.video.videoWidth,this.canvas.height=this.video.videoHeight;const e=new window.cv.Mat(this.video.videoHeight,this.video.videoWidth,window.cv.CV_8UC4),t=new window.cv.Mat(this.video.videoHeight,this.video.videoWidth,window.cv.CV_8UC4),n=new window.cv.VideoCapture(this.video),i=new window.cv.CascadeClassifier,o=new window.Utils("errorMessage"),s=this.haarcascadeUrl;o.createFileFromUrl(s,s,(()=>{i.load(s),this.facepluginopencv(n,e,t,i)}))}}))})).catch((e=>{console.error("An error occurred while accessing media devices: ",e)}))}isFaceInsideOval(e,canvas){const t=canvas.width/2,n=canvas.height/2,i=canvas.width/2,o=canvas.height/2;return(e.x+e.width/2-t)**2/i**2+(e.y+e.height/2-n)**2/o**2<=1}facepluginopencv(e,t,n,i){const o=Date.now();e.read(t);const s=new window.cv.Rect(t.cols/2-t.cols/(2*this.ZOOM_FACTOR),t.rows/2-t.rows/(2*this.ZOOM_FACTOR),t.cols/this.ZOOM_FACTOR,t.rows/this.ZOOM_FACTOR);let a=t.roi(s);window.cv.resize(a,n,new window.cv.Size(t.cols,t.rows),0,0,window.cv.INTER_LINEAR),this.instructionText.textContent="Keep Your Face In The Frame";let d=new window.cv.RectVector;try{if(i.detectMultiScale(t,d,1.5,3,0),1===d.size()){const e=d.get(0),n=(new window.cv.Rect(e.x,e.y,e.width,e.height),.14);let i=Math.max(0,e.x-e.width*n),o=Math.max(0,e.y-e.height*n),s=Math.min(t.cols-i,e.width*(1+2*n)),a=Math.min(t.rows-o,e.height*(1+2*n));const c=new window.cv.Rect(i,o,s,a);window.cv.rectangle(t,new window.cv.Point(c.x,c.y),new window.cv.Point(c.x+c.width,c.y+c.height),[5,255,0,255],2);const h=e.width*e.height,r=h/(Math.PI*(this.canvas.width/2)*(this.canvas.height/2))*100;if(this.isFaceInsideOval(e,this.canvas)){if(r<30)this.instructionText.textContent="Stay closer to the window";else if(r>=30&&r<=100&&(this.instructionText.textContent="Processing....",this.faceDetectionCount++,2===this.faceDetectionCount)){this.convertToBase64WithMetadata(c);const e=this.video.srcObject;if(e){e.getTracks().forEach((e=>e.stop()))}return}}else this.instructionText.textContent="Move inside the oval window";this.lastFaceDetectionTime=Date.now()}}catch(e){console.error("Error processing video:",e)}finally{d.delete()}this.isCanvasVisible&&(window.cv.flip(t,t,1),window.cv.imshow(this.canvas.id,t));const c=1e3/this.FPS-(Date.now()-o);setTimeout((()=>this.facepluginopencv(e,t,n,i)),c)}convertToBase64WithMetadata(e){const t=document.createElement("canvas");t.width=this.video.videoWidth,t.height=this.video.videoHeight;const n=t.getContext("2d");n.drawImage(this.video,0,0,t.width,t.height);const i=document.createElement("canvas");i.width=e.width,i.height=e.height;const o=i.getContext("2d"),s=n.getImageData(e.x,e.y,e.width,e.height);o.putImageData(s,0,0);const a={"0th":{[piexif.ImageIFD.Make]:"AccuraFace",[piexif.ImageIFD.Model]:"FaceDetectionCamera"}},d=piexif.dump(a),c=piexif.insert(d,i.toDataURL("image/jpeg",.92));this.onResultReceived&&(this.onResultReceived({base64:c,metadata:a}),document.querySelector("container").style.display="none")}addStyles(){const e=document.createElement("style");e.type="text/css",e.innerText="\n body {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100vh;\n margin: 0;\n background-color: rgb(255, 255, 255);\n font-family: Arial, sans-serif;\n flex-direction: column;\n }\n \n .container {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 20px;\n background-color: transparent;\n border-radius: 10px;\n }\n \n #instructionText {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 10px;\n background-color: #fff;\n color: rgb(10, 18, 131);\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\n border-radius: 5px;\n margin-bottom: 20px;\n font-size: 30px;\n font-weight: bold;\n }\n \n .camera-input {\n width: 250px;\n height: 370px;\n position: relative;\n overflow: hidden;\n border-radius: 50%;\n transform: scale(1.0); \n }\n \n #videoInput {\n width: 100%;\n height: 100%;\n object-fit: cover;\n transition: transform 0.3s ease-in-out;\n transform: scaleX(-1) scale(1.5); \n }\n \n #canvasOutput {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n transform: scale(1.5);\n }\n \n #response-text {\n font-size: 18px;\n color: #333;\n margin-top: 10px;\n }\n\n /* Desktop (default) */\n\n /* Laptop */\n @media (max-width: 1200px) {\n #instructionText {\n font-size: 26px;\n }\n }\n\n /* iPad / Tablet */\n @media (max-width: 992px) {\n #instructionText {\n font-size: 23px;\n }\n }\n\n /* Mobile */\n @media (max-width: 768px) {\n #instructionText {\n font-size: 15px;\n }\n }\n\n /* Small Mobile (Extra Small Devices) */\n @media (max-width: 480px) {\n #instructionText {\n font-size: 12px;\n }\n }\n }\n ",document.head.appendChild(e)}}
1
+ export default class FacePlugin{constructor(e,t){this.haarcascadeUrl=e,this.faceDetectionCount=0,this.onResultReceived=t,this.FPS=30,this.ZOOM_FACTOR=1.5,this.lastFaceDetectionTime=Date.now(),this.opencvLoaded=!1,this.createUI(),this.addStyles(),this.video=document.getElementById("videoInput"),this.canvas=document.getElementById("canvasOutput"),this.instructionText=document.getElementById("instructionText"),this.loader=document.getElementById("loader");const n=document.createElement("script");n.src="https://cdn.jsdelivr.net/npm/piexifjs@1.0.6/piexif.min.js",document.head.appendChild(n),this.checkOpenCV()}createUI(){const e=document.createElement("div");e.className="container";const t=document.createElement("div");t.className="camera-input",t.style.position="relative";const video=document.createElement("video");video.id="videoInput",video.width=640,video.height=480,video.autoplay=!0,video.muted=!0;const canvas=document.createElement("canvas");canvas.id="canvasOutput",canvas.style.display="none";const n=document.createElement("div");n.id="loader",n.className="loader",n.style.display="none";const i=document.createElement("p");i.id="instructionText",t.appendChild(video),t.appendChild(canvas),t.appendChild(n),e.appendChild(t),e.appendChild(i),document.body.appendChild(e)}checkOpenCV(){const e=()=>{window.cv?(this.opencvLoaded=!0,this.openCvReady()):setTimeout(e,100)};e()}openCvReady(){navigator.mediaDevices.getUserMedia({video:!0,audio:!1}).then((e=>{this.video.srcObject=e,this.video.play(),this.isCanvasVisible=!1,this.video.addEventListener("loadedmetadata",(()=>{if(this.video.videoWidth&&this.video.videoHeight){this.video.width=this.video.videoWidth,this.video.height=this.video.videoHeight,this.canvas.width=this.video.videoWidth,this.canvas.height=this.video.videoHeight;const e=new window.cv.Mat(this.video.videoHeight,this.video.videoWidth,window.cv.CV_8UC4),t=new window.cv.Mat(this.video.videoHeight,this.video.videoWidth,window.cv.CV_8UC4),n=new window.cv.VideoCapture(this.video),i=new window.cv.CascadeClassifier,o=new window.Utils("errorMessage"),s=this.haarcascadeUrl;o.createFileFromUrl(s,s,(()=>{i.load(s),this.facepluginopencv(n,e,t,i)}))}}))})).catch((e=>{console.error("An error occurred while accessing media devices: ",e)}))}isFaceInsideOval(e,canvas){const t=canvas.width/2,n=canvas.height/2,i=canvas.width/2,o=canvas.height/2;return(e.x+e.width/2-t)**2/i**2+(e.y+e.height/2-n)**2/o**2<=1}facepluginopencv(e,t,n,i){const o=Date.now();e.read(t);const s=new window.cv.Rect(t.cols/2-t.cols/(2*this.ZOOM_FACTOR),t.rows/2-t.rows/(2*this.ZOOM_FACTOR),t.cols/this.ZOOM_FACTOR,t.rows/this.ZOOM_FACTOR);let a=t.roi(s);window.cv.resize(a,n,new window.cv.Size(t.cols,t.rows),0,0,window.cv.INTER_LINEAR),this.instructionText.textContent="Keep Your Face In The Frame";let d=new window.cv.RectVector;try{if(i.detectMultiScale(t,d,1.5,3,0),1===d.size()){const e=d.get(0),n=(new window.cv.Rect(e.x,e.y,e.width,e.height),.14);let i=Math.max(0,e.x-e.width*n),o=Math.max(0,e.y-e.height*n),s=Math.min(t.cols-i,e.width*(1+2*n)),a=Math.min(t.rows-o,e.height*(1+2*n));const c=new window.cv.Rect(i,o,s,a);window.cv.rectangle(t,new window.cv.Point(c.x,c.y),new window.cv.Point(c.x+c.width,c.y+c.height),[5,255,0,255],2);const h=e.width*e.height,r=h/(Math.PI*(this.canvas.width/2)*(this.canvas.height/2))*100;if(this.isFaceInsideOval(e,this.canvas)){if(r<30)this.instructionText.textContent="Stay closer to the window";else if(r>=30&&r<=100&&(this.instructionText.textContent="Processing....",this.faceDetectionCount++,2===this.faceDetectionCount)){this.convertToBase64WithMetadata(c);const e=this.video.srcObject;if(e){e.getTracks().forEach((e=>e.stop()))}return}}else this.instructionText.textContent="Move inside the oval window";this.lastFaceDetectionTime=Date.now()}}catch(e){console.error("Error processing video:",e)}finally{d.delete()}this.isCanvasVisible&&(window.cv.flip(t,t,1),window.cv.imshow(this.canvas.id,t));const c=1e3/this.FPS-(Date.now()-o);setTimeout((()=>this.facepluginopencv(e,t,n,i)),c)}convertToBase64WithMetadata(e){const t=document.createElement("canvas");t.width=this.video.videoWidth,t.height=this.video.videoHeight;const n=t.getContext("2d");n.drawImage(this.video,0,0,t.width,t.height);const i=document.createElement("canvas");i.width=e.width,i.height=e.height;const o=i.getContext("2d"),s=n.getImageData(e.x,e.y,e.width,e.height);o.putImageData(s,0,0);const a={"0th":{[piexif.ImageIFD.Make]:"AccuraFace",[piexif.ImageIFD.Model]:"FaceDetectionCamera"}},d=piexif.dump(a),c=piexif.insert(d,i.toDataURL("image/jpeg",.92));this.onResultReceived&&(document.querySelector("container").style.display="none",this.onResultReceived({base64:c,metadata:a}))}addStyles(){const e=document.createElement("style");e.type="text/css",e.innerText="\n body {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100vh;\n margin: 0;\n background-color: rgb(255, 255, 255);\n font-family: Arial, sans-serif;\n flex-direction: column;\n }\n \n .container {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 20px;\n background-color: transparent;\n border-radius: 10px;\n }\n \n #instructionText {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 10px;\n background-color: #fff;\n color: rgb(10, 18, 131);\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\n border-radius: 5px;\n margin-bottom: 20px;\n font-size: 30px;\n font-weight: bold;\n }\n \n .camera-input {\n width: 250px;\n height: 370px;\n position: relative;\n overflow: hidden;\n border-radius: 50%;\n transform: scale(1.0); \n }\n \n #videoInput {\n width: 100%;\n height: 100%;\n object-fit: cover;\n transition: transform 0.3s ease-in-out;\n transform: scaleX(-1) scale(1.5); \n }\n \n #canvasOutput {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n transform: scale(1.5);\n }\n \n #response-text {\n font-size: 18px;\n color: #333;\n margin-top: 10px;\n }\n\n /* Desktop (default) */\n\n /* Laptop */\n @media (max-width: 1200px) {\n #instructionText {\n font-size: 26px;\n }\n }\n\n /* iPad / Tablet */\n @media (max-width: 992px) {\n #instructionText {\n font-size: 23px;\n }\n }\n\n /* Mobile */\n @media (max-width: 768px) {\n #instructionText {\n font-size: 15px;\n }\n }\n\n /* Small Mobile (Extra Small Devices) */\n @media (max-width: 480px) {\n #instructionText {\n font-size: 12px;\n }\n }\n }\n ",document.head.appendChild(e)}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "accurafaceplugin",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "",
5
5
  "main": "./src/accura.js",
6
6
  "scripts": {