You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
import {
Animated,
Dimensions,
Image,
PermissionsAndroid,
Platform,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import {useEffect, useRef, useState} from 'react';
import {
Frame,
useCameraDevice,
Camera as VCamera,
} from 'react-native-vision-camera';
import {
Face,
Camera,
FaceDetectionOptions,
} from 'react-native-vision-camera-face-detector';
import CustomButton from '../components/Button';
import Container from '../components/Container';
import AppHeader from '../components/AppHeader';
import Icon from 'react-native-vector-icons/Feather';
import {appHeaderIcon, CameraIcon, warningLogo} from '../utils/storage/icon';
import {moderateScale} from '../theme/Responsive';
import {colors} from '../theme';
import ImagePickerComponent from '../components/ImagePickerComponent';
import {launchImageLibrary} from 'react-native-image-picker';
import {setSelectedImage} from '../redux/slice/imagePickerSlice';
import {useDispatch} from 'react-redux';
import Toast from 'react-native-toast-message';
import {useNavigation} from '@react-navigation/native';
import LinearGradient from 'react-native-linear-gradient';
import PreviewPictures from '../components/PreviewPictures';
// Calculate the center point of the guide box
const guideBoxCenterX = GUIDE_BOX_LEFT + GUIDE_BOX_WIDTH / 2;
const guideBoxCenterY = GUIDE_BOX_TOP + GUIDE_BOX_HEIGHT / 2;
// Calculate the size of the circle based on the guide box dimensions
const circleSize = Math.min(GUIDE_BOX_WIDTH * 0.8, GUIDE_BOX_HEIGHT * 0.8);
// Calculate the position to center the circle
const circleLeft = guideBoxCenterX - circleSize / 1;
const circleTop = guideBoxCenterY - circleSize / 2;
// Scale factor for face bounds
const scaleFactor = Platform.OS === 'ios' ? 0.8 : 1;
{/* Only show capture button when face is detected /}
<View style={{justifyContent: 'flex-end'}}>
<TouchableOpacity
style={[
styles.captureButton,
isCapturing && styles.capturingButton,
]}
onPress={takePicture}
disabled={photoTaken || isCapturing}>
@DikshantDML401 There's really a lot of code, styles, etc.. (also it's bad formated) in your issue. Please edit it and provide only a minimal reproducible example
import {
Animated,
Dimensions,
Image,
PermissionsAndroid,
Platform,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import {useEffect, useRef, useState} from 'react';
import {
Frame,
useCameraDevice,
Camera as VCamera,
} from 'react-native-vision-camera';
import {
Face,
Camera,
FaceDetectionOptions,
} from 'react-native-vision-camera-face-detector';
import CustomButton from '../components/Button';
import Container from '../components/Container';
import AppHeader from '../components/AppHeader';
import Icon from 'react-native-vector-icons/Feather';
import {appHeaderIcon, CameraIcon, warningLogo} from '../utils/storage/icon';
import {moderateScale} from '../theme/Responsive';
import {colors} from '../theme';
import ImagePickerComponent from '../components/ImagePickerComponent';
import {launchImageLibrary} from 'react-native-image-picker';
import {setSelectedImage} from '../redux/slice/imagePickerSlice';
import {useDispatch} from 'react-redux';
import Toast from 'react-native-toast-message';
import {useNavigation} from '@react-navigation/native';
import LinearGradient from 'react-native-linear-gradient';
import PreviewPictures from '../components/PreviewPictures';
const {width: SCREEN_WIDTH, height: SCREEN_HEIGHT} = Dimensions.get('window');
const GUIDE_BOX_WIDTH = SCREEN_WIDTH * 0.7;
const GUIDE_BOX_HEIGHT = GUIDE_BOX_WIDTH * 1.3;
const GUIDE_BOX_TOP = (SCREEN_HEIGHT - GUIDE_BOX_HEIGHT) / 2;
const GUIDE_BOX_LEFT = (SCREEN_WIDTH - GUIDE_BOX_WIDTH) / 2;
const FaceOverlay = ({face, isFaceInPosition}: any) => {
if (!face) return null;
const {bounds} = face;
// Calculate the center point of the guide box
const guideBoxCenterX = GUIDE_BOX_LEFT + GUIDE_BOX_WIDTH / 2;
const guideBoxCenterY = GUIDE_BOX_TOP + GUIDE_BOX_HEIGHT / 2;
// Calculate the size of the circle based on the guide box dimensions
const circleSize = Math.min(GUIDE_BOX_WIDTH * 0.8, GUIDE_BOX_HEIGHT * 0.8);
// Calculate the position to center the circle
const circleLeft = guideBoxCenterX - circleSize / 1;
const circleTop = guideBoxCenterY - circleSize / 2;
// Scale factor for face bounds
const scaleFactor = Platform.OS === 'ios' ? 0.8 : 1;
return (
<Animated.View
style={[
styles.faceOverlay,
{
left: Platform.OS === 'ios' ? circleLeft : bounds.x * scaleFactor,
top: Platform.OS === 'ios' ? circleTop : bounds.y * scaleFactor,
width:
Platform.OS === 'ios' ? circleSize : bounds.width * scaleFactor,
height:
Platform.OS === 'ios' ? circleSize : bounds.height * scaleFactor,
borderColor: isFaceInPosition ? 'green' : 'yellow',
},
]}
/>
);
};
export default function Home() {
const dispatch = useDispatch();
const navigation = useNavigation();
const [hasPermission, setHasPermission] = useState<boolean | null>(null);
const [isCameraOpen, setIsCameraOpen] = useState(false);
const cameraRef = useRef(null);
const [capturedPhoto, setCapturedPhoto] = useState(null);
const [photoTaken, setPhotoTaken] = useState(false);
const [currentFace, setCurrentFace] = useState(null);
const [isCapturing, setIsCapturing] = useState(false);
const [isFaceInPosition, setIsFaceInPosition] = useState(false);
// const [tempImageData, setTempImageData] = useState<{
// uri: string;
// type: string;
// name: string;
// } | null>(null);
const device = useCameraDevice('front');
// const {faces, error, status} = useFacesInPhoto(tempImageData?.uri || '');
const faceDetectionOptions = useRef({
performanceMode: 'fast',
contourMode: 'all',
trackingEnabled: true,
}).current;
useEffect(() => {
(async () => {
const isPermission = await VCamera.requestCameraPermission();
if (isPermission === 'granted') {
console.log('granted');
await requestGalleryPermission();
}
setHasPermission(isPermission === 'granted');
})();
}, []);
const showToastError = (error: any) => {
console.log('Toast error triggered with:', error);
Toast.show({
type: 'error',
text1: 'Error',
text2:
typeof error === 'string'
? error
: 'Face should cover at least 50% of the photo, try again!',
});
};
function handleFacesDetection(faces: Face[], frame: Frame) {
if (faces.length >= 1) {
const face = faces[0];
const {bounds} = face;
}
const openCamera = () => {
setIsCameraOpen(true);
setPhotoTaken(false);
setIsCapturing(false);
};
const closeCamera = () => {
setIsCameraOpen(false);
setIsCapturing(false);
};
const takePicture = async () => {
if (cameraRef.current && !photoTaken && !isCapturing) {
setIsCapturing(true);
try {
console.log('Attempting to take picture...');
const photo = await cameraRef.current.takePhoto({
qualityPrioritization: 'speed',
});
console.log('Photo taken:', photo.path);
};
const requestGalleryPermission = async () => {
if (Platform.OS === 'android') {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.READ_MEDIA_IMAGES,
{
title: 'Gallery Permission',
message: 'App needs access to your gallery to select images',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
},
);
return granted === PermissionsAndroid.RESULTS.GRANTED;
} catch (err) {
console.error('Permission error:', err);
return false;
}
}
return true; // iOS handles permissions differently
};
const pickImage = async () => {
try {
// Check for permissions first
const hasGalleryPermission = await requestGalleryPermission();
if (!hasGalleryPermission) {
console.log('Gallery permission denied');
Toast.show({
type: 'error',
text1: 'Permission Denied',
text2: 'Please enable gallery access in your device settings',
});
return;
}
};
const confirmPhoto = () => {
if (capturedPhoto) {
dispatch(setSelectedImage(capturedPhoto));
navigation.navigate('AnalyzePhoto', {imageUri: capturedPhoto.uri});
closeCamera();
}
};
const retakePhoto = () => {
setCapturedPhoto(null);
setPhotoTaken(false);
};
const flipCamera = () => {
// Implementation for camera flip if needed
};
console.log(hasPermission, 'hasPermission');
if (hasPermission === null) {
return ;
}
if (hasPermission === false) {
return No access to camera;
}
const gradientColors = ['#7A4BFF66', '#D241DA66'];
return (
<>
{isCameraOpen ? (
{!!device && (
)}
{!photoTaken && (
<>
<View
style={[
styles.guideBox,
isFaceInPosition
? styles.guideBoxActive
: styles.guideBoxInactive,
]}
/>
{currentFace && (
<>
{/* Only show capture button when face is detected /}
<View style={{justifyContent: 'flex-end'}}>
<TouchableOpacity
style={[
styles.captureButton,
isCapturing && styles.capturingButton,
]}
onPress={takePicture}
disabled={photoTaken || isCapturing}>
</>
)}
</>
)}
{photoTaken && (
)}
) : (
<Container renderHeader={}>
Upload your Photo
To get accurate results
Image should be front facing
{/ <View style={{ justifyContent: "flex-end" }}>
<TouchableOpacity
style={[
styles.captureButton,
isCapturing && styles.capturingButton,
]}
onPress={takePicture}
disabled={photoTaken || isCapturing}
>
*/}
Face should cover at least 50% of the photo
<LinearGradient
colors={gradientColors}
start={{x: 0, y: 0}}
end={{x: 1, y: 0}}
style={styles.dividerStyle}
/>
Or
<LinearGradient
colors={gradientColors}
start={{x: 0, y: 0}}
end={{x: 1, y: 0}}
style={styles.dividerStyle}
/>
)}
</>
);
}
const styles = StyleSheet.create({
titleStyle: {
fontSize: moderateScale(24),
fontWeight: '600',
color: colors.light,
paddingBottom: moderateScale(16),
fontFamily: 'Poppins-SemiBold',
},
titleWrapper: {
alignItems: 'center',
justifyContent: 'center',
marginTop: moderateScale(20),
},
warningWrapper: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingTop: moderateScale(12),
paddingBottom: moderateScale(30),
gap: 10,
},
subTitleStyle: {
fontSize: moderateScale(12),
fontWeight: '400',
color: colors.light,
fontFamily: 'Poppins-Regular',
},
warningWrapperStyle: {
flexDirection: 'row',
alignItems: 'center',
maxWidth: moderateScale(150),
backgroundColor: '#FFFFFF1A',
borderRadius: moderateScale(40),
height: moderateScale(44),
paddingHorizontal: moderateScale(8),
},
warningWrapperStylee: {
flexDirection: 'row',
alignItems: 'center',
maxWidth: moderateScale(180),
backgroundColor: '#FFFFFF1A',
borderRadius: moderateScale(40),
height: moderateScale(44),
paddingHorizontal: moderateScale(8),
},
warningLogoStyle: {
width: moderateScale(25),
height: moderateScale(25),
marginRight: moderateScale(8),
},
warningTextLeft: {
fontSize: moderateScale(11),
fontWeight: '400',
color: colors.light,
maxWidth: moderateScale(100),
paddingRight: moderateScale(10),
fontFamily: 'Poppins-Regular',
},
warningText: {
fontSize: moderateScale(11),
fontWeight: '400',
color: colors.light,
maxWidth: moderateScale(140),
paddingRight: moderateScale(8),
fontFamily: 'Poppins-Regular',
},
btnContainerStyle: {
marginVertical: moderateScale(30),
},
btnTitleStyle: {
fontSize: moderateScale(18),
fontWeight: '600',
},
dividerWrapper: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
dividerStyle: {
height: 0.5,
width: moderateScale(150),
},
dividerText: {
fontSize: moderateScale(14),
color: colors.light,
marginHorizontal: moderateScale(10),
fontFamily: 'Poppins-Regular',
},
cameraContainer: {
flex: 1,
width: SCREEN_WIDTH,
height: SCREEN_HEIGHT,
justifyContent: 'center',
alignItems: 'center',
},
guideBox: {
position: 'absolute',
width: GUIDE_BOX_WIDTH,
height: GUIDE_BOX_HEIGHT,
borderWidth: 2,
borderRadius: 10,
},
guideBoxInactive: {
borderColor: 'white',
},
guideBoxActive: {
borderColor: 'green',
},
confirmationContainer: {
position: 'absolute',
bottom: 30,
flexDirection: 'row',
justifyContent: 'space-around',
width: '100%',
},
confirmationButton: {
backgroundColor: 'rgba(0, 0, 0, 0.5)',
padding: 15,
borderRadius: 30,
},
faceOverlay: {
position: 'absolute',
borderWidth: 2,
borderRadius: 999,
backgroundColor: 'transparent',
},
idealFaceCircle: {
position: 'absolute',
width: GUIDE_BOX_WIDTH,
height: GUIDE_BOX_HEIGHT,
borderRadius: GUIDE_BOX_WIDTH / 2,
borderWidth: 1,
borderColor: 'rgba(255, 255, 255, 0.3)',
borderStyle: 'dashed',
top: GUIDE_BOX_TOP,
left: GUIDE_BOX_LEFT,
},
camera: {
flex: 1,
},
buttonContainer: {
flex: 1,
backgroundColor: 'transparent',
flexDirection: 'row',
justifyContent: 'space-around',
margin: 20,
},
button: {
alignSelf: 'flex-end',
alignItems: 'center',
padding: 10,
},
text: {
fontSize: 16,
color: 'white',
},
captureButton: {
width: 70,
height: 70,
borderRadius: 35,
backgroundColor: 'white',
justifyContent: 'center',
alignItems: 'center',
},
innerCaptureButton: {
width: 60,
height: 60,
borderRadius: 30,
backgroundColor: 'white',
borderWidth: 2,
borderColor: '#000',
},
capturingButton: {
opacity: 0.5,
},
});
The text was updated successfully, but these errors were encountered: