- SDK Version: 38.0.8
- Platforms(Android/iOS/web/all): tried only on Android
Hello Geeks…
I am new to react-native, I am trying to hands-on for face detecting with below git repo as ref: expo-ar/ex3.md at master · NewThingsCo/expo-ar · GitHub
I tried to adapt the code to function style rather than old class type. Thing seems to work for some time, but within a minute screen turns black with the rendered mask component still visible. Below is the modified version of repo:
- App.js
import React, { useState, useEffect, createRef } from 'react';
import { Text, View, TouchableOpacity, StyleSheet} from 'react-native';
import { Container, Header, Content, Tab, Tabs } from 'native-base';
import { Camera } from 'expo-camera';
import * as FaceDetector from 'expo-face-detector';
import Mask from './Mask.js';
import ActionSheet from "react-native-actions-sheet";
export default function App() {
const [hasPermission, setHasPermission] = useState(null);
const [type, setType] = useState(Camera.Constants.Type.front);
const [faces,setFaces] = useState([]);
const [faceDetected,setFaceDetected ]= useState(false);
const actionSheetRef = createRef();
useEffect(() => {
(async () => {
const { status } = await Camera.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
if (hasPermission === null) {
return <Container/>;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
const onFacesDetected = async (faces)=>{
if(faces.faces<1)
return;
setFaces(faces.faces);
setFaceDetected(true)
}
const onFaceDetectionError = async(error) => {
setFaceDetected(false);
console.log(error);
}
return (
<View style={{ flex: 1}}>
<Camera style={{ flex: 1, flexDirection:'row'}}
type={type}
faceDetectorSettings={{
mode: FaceDetector.Constants.Mode.fast,
detectLandmarks: FaceDetector.Constants.Landmarks.all,
tracking: true,
minDetectionInterval:300
}}
onFacesDetected={onFacesDetected}
onFacesDetectionError={onFaceDetectionError}
>
{
faceDetected?faces.map(face => {
return <Mask key={face.faceID} face={face} />
}):undefined
}
</Camera>
</View>
);
}
const Style = new StyleSheet.create(
{
bottomContainer : {
flex: 1,
height : 100,
alignSelf: 'flex-end',
alignItems: "center",
backgroundColor: 'transparent',
flexDirection: 'row',
justifyContent: "space-between"
},
}
);
- Mask.js
import React,{useState, useEffect} from 'react';
import {View } from 'react-native';
const Mask = ({
face :{
bounds:{
origin:{
x: contatinerX,
y: contatinerY,
},
size: {width : faceWidth}
},
leftEyePosition,
rightEyePosition,
leftEarPosition,
rightEarPosition
}
}) => {
const eyeWidth = faceWidth/4
const pupilWidth = eyeWidth/3
const translatedEyePositionX = eyePosition => eyePosition.x - eyeWidth/2 - contatinerX
const translatedEyePositionY = eyePosition => eyePosition.y - eyeWidth/2 - contatinerY
const translatedLeftEyePosition = {
x:translatedEyePositionX(leftEyePosition),
y:translatedEyePositionY(leftEyePosition)
};
const translatedRightEyePosition = {
x:translatedEyePositionX(rightEyePosition),
y:translatedEyePositionY(rightEyePosition)
};
const leftEarBottomPosition = {
x: translatedEyePositionX(leftEarPosition),
y: translatedEyePositionX(leftEarPosition),
};
const rightEarBottomPosition = {
x: translatedEyePositionX(rightEarPosition),
y: translatedEyePositionX(rightEarPosition),
};
const eyeStyle = (eyePosition,eyeBorderWidth = eyeWidth /10) =>({
position:'absolute',
left: eyePosition.x,
top: eyePosition.y,
borderRadius: eyeWidth,
width:eyeWidth,
height : eyeWidth,
borderWidth: eyeBorderWidth,
borderColor: 'black',
backgroundColor: 'yellow',
alignItems: 'center',
flex:1
});
const pupilStyle = (eyePosition) =>({
borderRadius: pupilWidth,
width: pupilWidth,
height : pupilWidth,
backgroundColor: 'black',
});
return(
<View style={{position:'absolute',left:contatinerX, top :contatinerY}}>
<View style={{...eyeStyle(translatedLeftEyePosition)}}>
<View style={{...pupilStyle(translatedLeftEyePosition)}}/>
</View>
<View style={{...eyeStyle(translatedRightEyePosition)}}>
<View style={{...pupilStyle(translatedRightEyePosition)}}/>
</View>
</View>
);
};
export default Mask
below is the image when it gets stuck: screen stuck after few sec
A new mask component is partly created everytime. I think every time face is detected, react is trying to render a new mask rather than updating the one which already exist. Can someone guide me things I am doing wrong over here to fix it.