I have a implemented a camera feature that will detect your face, and the dimensions is set to width: 330px, and height: 550px.
When I ran it on the computer browser (both big screen and mobile preview through F12), the camera’s dimension is correct and no problems whatsoever. As seen in the following figure below. Sorry, I cannot show the actual website, as it is confidential at the moment.
However, when I ran it on my 13 Pro Max, there are problems.
First: it seems like the code got the width and height of my cam settings mixed up. In other words, the width becomes the height, and height becomes the width, as seen below:
Upon taking a picture, the camera then shows the correct dimensions as it was during the RWD preview. However, the face detection feature lags terribly. This always happen for the first time you fire up the app.
And when I rotate the phone sideways, it didn’t lag, and the cam was shown in the correct dimension, but when I rotate it back to the normal, the dimension values were mixed again, this showing the longer webcam width. Funnier thing is:
the face detection works smoothly with the wrong dimensions, and it lags to the point it’s almost unusable with the correct dimension.
Here is my code:
HTML Code
<div id="liveView" class="videoView flex justify-center items-center py-4 px-12">
<div style="position: relative" class="border:1px solid black; web-cam flex-shrink-0" >
<video width="330" height="500" id="webcam" style=" position: abso; left: 0px; top: 0px " class="bg-bgWebCam flex-shrink-0" autoplay playsinline ></video>
<canvas width="330" height="500" id="photoTaken" style="position: absolute; overflow-x:auto; left: 0px; top: 0px" class="photoTaken justify-center items-center"></canvas>
<img class="testImg bg-teal-300" src="" id="testImg">
</div>
</div>
<!-- <div class="videoView flex justify-center items-center py-6 px-12"> -->
<div>
<button id="captureButton" class="mdc-button mdc-button--raised font-default hover:bg-lime-600 bg-teal-500 text-black py-2 px-4 rounded-full px-4 py-2 mx-2 my-2" disabled><i class="fa fa-camera"></i></button>
<div class="px-4 py-2 mx-2 my-2" hidden>
<label for="angleVal" >Show Angle Score</label>
<input type="checkbox" id="angleVal">
</div>
</div>
<!-- </div> -->
<div class="blend-shapes">
<p id="camInst"></p>
<p class="blend-shapes-list" id="angleValues"></p>
</div>
Variables
//Webcam Video and Canvas Settings
const video = document.getElementById("webcam") as HTMLVideoElement;
const canvas = document.getElementById("photoTaken") as HTMLCanvasElement;
const canvasCtx = canvas.getContext("2d");
const testImg=document.getElementById("testImg")
canvas.hidden=true;
let faceLandmarker;
let runningMode: "IMAGE" | "VIDEO" = "IMAGE";
let predictionsRunning: Boolean = true;
const videoWidth = video.width
const videoHeight = video.height
let media
const resolution={ w: 330, h: 500 };
const cameraSize = { w: 330, h: 500 };
Streamvid, the function that is called upon startup:
function streamVid()
{
media = navigator.mediaDevices.getUserMedia({
audio: false,
video: {
width: { ideal: resolution.w },
height: { ideal: resolution.h }
}
}).then(function(stream) {
video.srcObject = stream;
video.addEventListener("loadeddata", predictWebcam); //Predict WebCam will detect the face.
});
}
Capture Button
function capture()
{
let toggleSignal = document.getElementById('toggleSignal');
let style = window.getComputedStyle(toggleSignal, null).getPropertyValue('font-size');
var fontSize = parseFloat(style);
//Flip it over//
testImg.style.transform = "scaleX(-1)";
// canvas.style.transform = "scaleX(1)";
canvas.hidden=true
maskEnabled=false
// canvas.getContext('2d').drawImage(video, 0, 0,368+200, 368);
let photoWidth=0
let xTranslate
if(fontSize==30 || fontSize==35)
{
photoWidth=canvas.width+500
xTranslate=-175
}
else
{
photoWidth=canvas.width
xTranslate=0
}
console.log("Font Size: "+fontSize)
canvas.getContext('2d').drawImage(video, xTranslate, 0,photoWidth, canvas.height);
// canvas.getContext('2d').drawImage(video, 0, 0,canvas.height, canvas.);
if(!isPhotoTaken)
{
predictionsRunning = false;
video.hidden=true
testImg.hidden=false
const FLASH_TIMEOUT=50
setTimeout(() => {
isShotPhoto = false;
}, FLASH_TIMEOUT);
captureButton.disabled=false
captureButton.innerHTML=`<i class="fa fa-close"></i>`
}
else
{
isPhotoTaken=true
// isShotPhoto = true
streamVid();
console.log("VW: "+videoWidth)
predictionsRunning = true;
video.hidden=false
testImg.hidden=true
captureButton.innerHTML=`<i class="fa fa-camera"></i>`
if(automaticCaptureIsOn==true)
{
captureButton.hidden=true
}
}
isPhotoTaken = !isPhotoTaken;
imgInB64=canvas.toDataURL();
testImg.src=imgInB64
}
CSS
<style>
@font-face {
font-family: Bree;
src: url("../../bree-2-cufonfonts/Bree Light Oblique.otf");
}
.camTitle{
font-family: Bree;
font-style: Italic;
font-weight: lighter
}
.web-cam {
border-radius: 200px;
-webkit-mask-image: -webkit-radial-gradient(circle, white 100%, black 100%);
}
canvas{
width: 330px;
height: 500px;
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
border-radius: 200px;
background-clip: content-box;
border: 1px solid black;
padding: 12px;
}
video{
width: 330px;
height: 500px;
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
border: 1px solid black;
border-radius: 200px;
background-clip: content-box;
padding: 12px;
z-index: 1;
}
testImg{
width: 330px;
height: 500px;
border-radius: 200px;
background-clip: content-box;
border: 1px solid black;
padding: 12px;
}
</style>
Is there a way to prevent the camera from rotating, and face detection works well on device?