-
Notifications
You must be signed in to change notification settings - Fork 20
Open
Description
Hi there,
So I have been using this library for Android with no issues, it detects face with ease, however, on iOS device, the faces
property is just an empty array, its not able to detect any face whatsoever.
Here's the screen file
//facial-scan.tsx
import React, { useRef, useState } from 'react';
import { Button, Image, View, StyleSheet, Dimensions, Text } from 'react-native';
import { Camera, useCameraDevice, useCameraPermission } from 'react-native-vision-camera';
import Svg, { Rect, Mask } from 'react-native-svg';
import { useRouter } from 'expo-router';
import { layout } from '@/styles/common';
import { Button as ButtonComponent, Header } from '@/components';
import { typography } from '@/styles/typography';
import { useIsFocused } from '@react-navigation/native';
import { useFacesInPhoto, useFaceDetection } from '@infinitered/react-native-mlkit-face-detection';
const { width, height } = Dimensions.get('window');
const horizontalPadding = 20;
const maskMarginTop = 30;
const frameWidth = width - horizontalPadding * 2;
const frameHeight = frameWidth;
const frameX = (width - width * 0.9) / 2;
const frameY = maskMarginTop;
export default function FaceRecognitionScreen() {
const model = useFaceDetection();
const device = useCameraDevice('front');
const router = useRouter();
const [photoUri, setPhotoUri] = useState<string | null>(null);
const { hasPermission, requestPermission } = useCameraPermission();
// This hook returns `true` if the screen is focused, `false` otherwise
const isFocused = useIsFocused();
// const appState = useAppState()
const isActive = isFocused;
const cameraRef = useRef<Camera>(null);
const { faces, error } = useFacesInPhoto(photoUri ?? undefined);
const takePicture = async () => {
if (!cameraRef.current) return;
try {
const photo = await cameraRef.current?.takePhoto({ flash: 'off' });
try {
const result = await model.detectFaces(`file://${photo.path}`);
// Comment below line prior to submitting new release APK
// router.replace('/(auth)/review-info');
console.log('result: ', result)
// Uncomment below line prior during development with physical device
if (!result || !faces.length) {
// Handle undefined result case
alert('No faces detected!');
return;
}
else if(faces.length === 1) {
router.navigate('/(auth)/review-info');
}
alert(`Faces detected!, ${faces.length}, ${JSON.stringify(faces)}`);
} catch (error) {
// Handle error case
console.error('Face detection failed:', error);
}
} catch (err) {
console.error('Error taking photo:', err);
}
};
return (
<View style={layout.fill}>
<Header onPressCallback={() => {
router.back();
}} />
<View
style={styles.cameraContainer}
>
{/* Camera */}
{device && (
<View style={styles.roundedCameraWrapper}>
{!hasPermission ? (
<View>
<Text style={styles.permissionPromptText}>
We need your permission to show the camera
</Text>
<Button onPress={requestPermission} title="grant permission" />
</View>
) : <Camera
style={StyleSheet.absoluteFill}
isActive={isActive}
device={device}
resizeMode="cover"
ref={cameraRef}
photo={true}
/>}
</View>
)}
{/* Masked Overlay */}
<Svg style={StyleSheet.absoluteFill}>
<Mask id="mask">
<Rect x="0" y="0" width={width} height={height} fill="white" />
<Rect
x={frameX}
y={frameY}
width={'90%'}
height={frameHeight}
rx={10}
ry={10}
fill="black"
/>
</Mask>
<Rect
y="0"
width={'100%'}
height={height * 0.75}
fill="#000000C7"
mask="url(#mask)"
rx={10}
ry={10}
/>
</Svg>
{/* Text inside frame */}
<View style={styles.textInFrameContainer}>
<Image source={require('@/assets/images/facial.png')} />
<Text style={styles.title}>Face Recognition</Text>
<Text style={styles.subtitle}>Try to keep your face within the frame</Text>
</View>
</View>
<View style={layout.buttonContainer}>
<ButtonComponent title="Submit" onPressCallback={takePicture} />
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
borderWidth: 3,
borderColor: 'red'
},
backButton: {},
title: {
fontSize: 18,
fontWeight: 'bold',
color: '#00C2CB',
},
subtitle: {
fontSize: 14,
color: '#fff',
marginTop: 5,
borderWidth: 2,
borderColor: 'red'
},
submitButton: {
position: 'absolute',
bottom: 40,
alignSelf: 'center',
backgroundColor: '#00C2CB',
// borderRadius: 999,
paddingVertical: 12,
paddingHorizontal: 40,
},
submitText: {
color: '#fff',
fontSize: 16,
fontWeight: 'bold',
},
textInFrameContainer: {
position: 'absolute',
alignItems: 'center',
justifyContent: 'space-evenly',
top: frameHeight * 0.65,
left: frameX - 20,
width: frameWidth,
height: 150
},
camera: {
width: '99.9%',
height: height * 0.75,
overflow: 'hidden',
borderColor: 'green',
borderWidth: 2
},
cameraContainer: {
marginTop: 20,
overflow: 'hidden',
flex: 1,
},
roundedCameraWrapper: {
width: '99.9%',
height: height * 0.75,
borderRadius: 10, // whatever radius you want
overflow: 'hidden',
alignSelf: 'center', // optional, if needed
borderWidth: 2,
borderColor: 'green', // optional
},
permissionPromptText: {
...typography.body,
color: 'white',
marginBottom: 10
},
});
and here is output from
await model.detectFaces(`file://${photo.path}`):
{"faces": [], "imagePath": "file://file///private/var/mobile/Containers/Data/Application/AD8AF7CF-043A-4125-970F-5ECB662C9016/tmp/9B9AEF52-9647-4259-9A3F-AA3BAFC6EB6B.jpg"}
Metadata
Metadata
Assignees
Labels
No labels