0

I am newer for using react-native, and wanna try to create a camera with filter. I'm blocked in step to recognize face. Have success to draw rectangle when face detected, but the problem is once it goes out of detection. The camera stop running as it fixes on the last real-time capture

Here is my code:

import { useState, useEffect, useRef } from 'react'
import { Camera } from 'expo-camera'
import * as MediaLibrary from 'expo-media-library'
import { Text, StyleSheet, View, TouchableOpacity } from 'react-native'
import Button from './Button'
import { Ionicons } from '@expo/vector-icons'
import * as FaceDetector from 'expo-face-detector'

export default function PCamera() {

const cameraRef = useRef(undefined)
const [faceDetected, setFaceDetected] = useState([])
const [lastImage, setImage] = useState(undefined)
const [hasUsePermssion, setUsePermission] = useState(false)
const [type, switchToType] = useState(Camera.Constants.Type.front)


const takePicture = async () => {
    if (cameraRef) {
        try {
            const options = {
                quality: 1,
                base64: true,
                exif: false,
            }
            const data = await cameraRef.current.takePictureAsync(options)
            setImage(data.uri)
            console.log(data)
        } catch (err) {
            console.error(err)
        }
    }
}

const swithMode = () => {
    switchToType(
        type === Camera.Constants.Type.front
            ? Camera.Constants.Type.back
            : Camera.Constants.Type.front
    )
}

const handleFacesDetected = ({ faces }) => {
    setFaceDetected(faces)
}

useEffect(() => {
    ;(async () => {
        const { status } = await Camera.requestCameraPermissionsAsync()
        if (status === 'granted') {
            setUsePermission(true)
        }
    })()
}, [])

if (hasUsePermssion === null) {
    return <View />
}
if (hasUsePermssion === false) {
    return <Text>No access to camera</Text>
}

return (
    <View style={styles.cameraContainer}>
        <View style={styles.overlay}>
            <Camera
                ref={cameraRef}
                style={styles.camera}
                type={type}
                onFacesDetected={handleFacesDetected}
                faceDetectorSettings={{
                    mode: FaceDetector.FaceDetectorMode.fast,
                    detectLandmarks: FaceDetector.FaceDetectorLandmarks.all,
                    runClassifications:
                        FaceDetector.FaceDetectorClassifications.none,
                    minDetectionInterval: 100,
                    tracking: true,
                }}
            >
                {faceDetected.length > 0 &&
                    faceDetected.map((face) => (
                        <View
                            key={face.faceID}
                            style={{
                                position: 'absolute',
                                borderWidth: 2,
                                borderColor: 'red',
                                left: face.bounds.origin.x,
                                top: face.bounds.origin.y,
                                width: face.bounds.size.width,
                                height: face.bounds.size.height,
                            }}
                        />
                    ))}
            </Camera>
        </View>

        <View style={styles.optionsContainer}>
            <View>
                <TouchableOpacity onPress={swithMode}>
                    <Text>
                        <Ionicons
                            name="camera-reverse-outline"
                            size={24}
                            color="black"
                        />
                    </Text>
                </TouchableOpacity>
            </View>
            <Button
                icon="camera"
                title="Take Photo"
                onPress={takePicture}
                style={styles.button}
            />
            <View>
                <Text>...</Text>
            </View>
        </View>
    </View>
)}

const styles = StyleSheet.create({
cameraContainer: {flex: 1,
},
overlay: {
    flex: 6,
    borderBottomStartRadius: 75,
    borderBottomEndRadius: 75,
    overflow: 'hidden',
},
camera: {
    flex: 1,
},
optionsContainer: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'space-around',
    alignItems: 'center',
},
})

N.B: Don't take care of the Button, it's a custom component and works well

Here is how look like the app after bugging

Kirill Novikov
  • 2,576
  • 4
  • 20
  • 33

0 Answers0