Cámara y Galería con Expo
Una de las ventajas más grandes de Expo es el acceso simplificado a las APIs nativas del dispositivo. Sin Expo, configurar la cámara en React Native requiere modificar archivos nativos de iOS y Android manualmente, que puede tomar horas y necesita conocimiento de Objective-C/Swift y Java/Kotlin.
Con expo-camera simplemente instalas la librería, declaras el permiso en app.json, y tienes acceso completo a la cámara frontal y trasera, zoom, flash y toma de fotos en minutos.
expo-image-picker da acceso a la galería de fotos del dispositivo y también a la cámara para capturar fotos o videos. Antes de acceder a recursos del dispositivo (cámara, galería, GPS, notificaciones), debes pedir permisos explícitos al usuario. Expo tiene una API unificada de permisos con requestPermissionsAsync(). iOS y Android tienen comportamientos diferentes: iOS solo pregunta una vez (si el usuario niega, debes mandarlo a Configuración), Android puede preguntar de nuevo.
import { CameraView, useCameraPermissions } from "expo-camera";
import * as ImagePicker from "expo-image-picker";
import { useState, useRef } from "react";
export function CamaraScreen() {
const [permiso, solicitarPermiso] = useCameraPermissions();
const [foto, setFoto] = useState(null);
const camaraRef = useRef(null);
if (!permiso) return <View />;
if (!permiso.granted) {
return (
<View style={styles.container}>
<Text>Necesitamos acceso a la cámara</Text>
<TouchableOpacity onPress={solicitarPermiso}>
<Text>Dar permiso</Text>
</TouchableOpacity>
</View>
);
}
const tomarFoto = async () => {
if (camaraRef.current) {
const resultado = await camaraRef.current.takePictureAsync({
quality: 0.8,
base64: false,
});
setFoto(resultado.uri);
}
};
return (
<View style={styles.container}>
{foto ? (
<>
<Image source={{ uri: foto }} style={styles.preview} />
<TouchableOpacity onPress={() => setFoto(null)}>
<Text>Tomar otra</Text>
</TouchableOpacity>
</>
) : (
<CameraView style={styles.camara} facing="back" ref={camaraRef}>
<TouchableOpacity style={styles.botonFoto} onPress={tomarFoto}>
<View style={styles.circulo} />
</TouchableOpacity>
</CameraView>
)}
</View>
);
}
// Galería de fotos
async function seleccionarImagen() {
const permiso = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (!permiso.granted) return null;
const resultado = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
aspect: [1, 1],
quality: 0.8,
});
if (!resultado.canceled) {
return resultado.assets[0].uri;
}
return null;
}
Practica esta lección
Resuelve los ejercicios del curso de React Native en la app, gratis y con corrección automática.
Empezar a practicar