Cours React Native · Module 6: Photos, appareil photo et son
expo-camera - Contrôle avancé de la caméra
Dans cette leçon5
Pour un contrôle total de la caméra, utilise expo-camera !
Installation
npx expo install expo-cameraVue caméra de base
import { CameraView, CameraType, useCameraPermissions } from 'expo-camera';
import { useState, useRef } from 'react';
function CameraScreen() {
const [facing, setFacing] = useState<CameraType>('back');
const [permission, requestPermission] = useCameraPermissions();
const cameraRef = useRef<CameraView>(null);
if (!permission) {
return <View />;
}
if (!permission.granted) {
return (
<View style={styles.container}>
<Text>Nous avons besoin d'accéder à la caméra</Text>
<Pressable onPress={requestPermission}>
<Text>Accorder les permissions</Text>
</Pressable>
</View>
);
}
const toggleCameraFacing = () => {
setFacing((current) => (current === 'back' ? 'front' : 'back'));
};
return (
<View style={styles.container}>
<CameraView
ref={cameraRef}
style={styles.camera}
facing={facing}
>
<View style={styles.controls}>
<Pressable onPress={toggleCameraFacing}>
<Ionicons name="camera-reverse" size={32} color="white" />
</Pressable>
</View>
</CameraView>
</View>
);
}Prendre des photos
function CameraWithCapture() {
const cameraRef = useRef<CameraView>(null);
const [photo, setPhoto] = useState<string | null>(null);
const takePicture = async () => {
if (cameraRef.current) {
const photo = await cameraRef.current.takePictureAsync({
quality: 0.8,
base64: false,
exif: true,
});
if (photo) {
setPhoto(photo.uri);
}
}
};
if (photo) {
return (
<View style={styles.previewContainer}>
<Image source={{ uri: photo }} style={styles.preview} />
<View style={styles.previewButtons}>
<Pressable onPress={() => setPhoto(null)}>
<Text>Reprendre</Text>
</Pressable>
<Pressable onPress={() => savePhoto(photo)}>
<Text>Enregistrer</Text>
</Pressable>
</View>
</View>
);
}
return (
<CameraView ref={cameraRef} style={styles.camera}>
<Pressable style={styles.captureButton} onPress={takePicture}>
<View style={styles.captureInner} />
</Pressable>
</CameraView>
);
}Scan de codes QR
import { CameraView, useCameraPermissions, BarcodeScanningResult } from 'expo-camera';
function QRScanner() {
const [permission, requestPermission] = useCameraPermissions();
const [scanned, setScanned] = useState(false);
const handleBarCodeScanned = (result: BarcodeScanningResult) => {
if (scanned) return;
setScanned(true);
Alert.alert(
'Code scanné !',
result.data,
[{ text: 'Scanner à nouveau', onPress: () => setScanned(false) }]
);
};
return (
<CameraView
style={styles.camera}
barcodeScannerSettings={{
barcodeTypes: ['qr', 'ean13', 'ean8'],
}}
onBarcodeScanned={handleBarCodeScanned}
>
<View style={styles.overlay}>
<View style={styles.scanArea} />
<Text style={styles.instruction}>Pointe la caméra vers un code QR</Text>
</View>
</CameraView>
);
}Flash
function CameraWithFlash() {
const [flash, setFlash] = useState<'off' | 'on' | 'auto'>('off');
const toggleFlash = () => {
setFlash((current) => {
if (current === 'off') return 'on';
if (current === 'on') return 'auto';
return 'off';
});
};
return (
<CameraView style={styles.camera} flash={flash}>
<Pressable onPress={toggleFlash}>
<Ionicons
name={flash === 'off' ? 'flash-off' : flash === 'on' ? 'flash' : 'flash-outline'}
size={28}
color="white"
/>
</Pressable>
</CameraView>
);
}expo-camera te donne un contrôle total sur la caméra de l'appareil !
Code de cette leçon : App.tsx
import React, { useState } from 'react';
import { View, Text, Pressable, StyleSheet, Alert } from 'react-native';
import { CameraView, useCameraPermissions, BarcodeScanningResult } from 'expo-camera';
export default function App() {
const [permission, requestPermission] = useCameraPermissions();
const [scanned, setScanned] = useState(false);
const handleBarCodeScanned = (result: BarcodeScanningResult) => {
if (scanned) return;
setScanned(true);
Alert.alert('Code scanné !', result.data, [
{ text: 'Scanner à nouveau', onPress: () => setScanned(false) },
]);
};
if (!permission?.granted) {
return (
<View style={styles.center}>
<Text style={styles.text}>Nous avons besoin d'accéder à la caméra</Text>
<Pressable style={styles.button} onPress={requestPermission}>
<Text style={styles.buttonText}>Autoriser l'accès</Text>
</Pressable>
</View>
);
}
return (
<CameraView
style={styles.camera}
barcodeScannerSettings={{ barcodeTypes: ['qr'] }}
// TODO : connecte la prop onBarcodeScanned à la fonction handleBarCodeScanned
>
<View style={styles.overlay}>
<Text style={styles.instruction}>Pointe la caméra vers un QR code</Text>
</View>
</CameraView>
);
}
const styles = StyleSheet.create({
center: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#1a5276' },
camera: { flex: 1 },
overlay: { flex: 1, justifyContent: 'flex-end', alignItems: 'center', paddingBottom: 60 },
instruction: { color: '#fff', fontSize: 16, backgroundColor: 'rgba(0,0,0,0.5)', padding: 10, borderRadius: 8 },
text: { color: '#fff', fontSize: 16, marginBottom: 16 },
button: { backgroundColor: '#2980b9', padding: 12, borderRadius: 8 },
buttonText: { color: '#fff', fontSize: 16 },
});Entrées de la documentation utilisées dans cette leçon
Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. Quel composant affiche l'aperçu de la caméra dans expo-camera ?
2. Quelles valeurs la prop 'facing' accepte-t-elle dans CameraView ?
Tâches pratiques dans le jeu
- Tri horizontal
Ordonne la prise d'une photo :
- Éditeur de code
Complète le code du scanner avec onBarcodeScanned.