1import React from 'react'; 2import { FaceFeature } from 'expo-face-detector'; 3import { View, Text, StyleSheet } from 'react-native'; 4 5const landmarkSize = 2; 6 7export const scaledFace = (scale: number) => ({ 8 faceID, 9 bounds, 10 rollAngle, 11 yawAngle, 12}: FaceFeature) => ( 13 <View 14 key={faceID} 15 style={[ 16 styles.face, 17 { 18 width: bounds.size.width * scale, 19 height: bounds.size.height * scale, 20 left: bounds.origin.x * scale, 21 top: bounds.origin.y * scale, 22 transform: [ 23 { perspective: 600 }, 24 { rotateZ: `${rollAngle!.toFixed(0)}deg` }, 25 { rotateY: `${yawAngle!.toFixed(0)}deg` }, 26 ], 27 }, 28 ]}> 29 <Text style={styles.faceText}>ID: {faceID}</Text> 30 <Text style={styles.faceText}>rollAngle: {rollAngle!.toFixed(0)}</Text> 31 <Text style={styles.faceText}>yawAngle: {yawAngle!.toFixed(0)}</Text> 32 </View> 33); 34 35export const scaledLandmarks = (scale: number) => (face: FaceFeature) => { 36 const renderLandmark = (position?: { x: number; y: number }) => 37 position && ( 38 <View 39 style={[ 40 styles.landmark, 41 { 42 left: (position.x - landmarkSize / 2) * scale, 43 top: (position.y - landmarkSize / 2) * scale, 44 }, 45 ]} 46 /> 47 ); 48 console.log('landmark', face); 49 return ( 50 <View key={`landmarks-${face.faceID}`}> 51 {renderLandmark(face.leftEyePosition)} 52 {renderLandmark(face.rightEyePosition)} 53 {renderLandmark(face.leftEarPosition)} 54 {renderLandmark(face.rightEarPosition)} 55 {renderLandmark(face.leftCheekPosition)} 56 {renderLandmark(face.rightCheekPosition)} 57 {renderLandmark(face.leftMouthPosition)} 58 {renderLandmark(face.mouthPosition)} 59 {renderLandmark(face.rightMouthPosition)} 60 {renderLandmark(face.noseBasePosition)} 61 {renderLandmark(face.bottomMouthPosition)} 62 </View> 63 ); 64}; 65 66export const face = scaledFace(1); 67export const landmarks = scaledLandmarks(1); 68 69const styles = StyleSheet.create({ 70 face: { 71 padding: 10, 72 borderWidth: 2, 73 borderRadius: 2, 74 position: 'absolute', 75 borderColor: '#FFD700', 76 justifyContent: 'center', 77 backgroundColor: 'rgba(0, 0, 0, 0.5)', 78 }, 79 landmark: { 80 width: landmarkSize, 81 height: landmarkSize, 82 position: 'absolute', 83 backgroundColor: 'red', 84 }, 85 faceText: { 86 color: '#FFD700', 87 fontWeight: 'bold', 88 textAlign: 'center', 89 margin: 10, 90 backgroundColor: 'transparent', 91 }, 92}); 93