Kurs React Native · Moduł 6: Zdjęcia, kamera i dźwięk
expo-image-picker - Wybór obrazów
W tej lekcji6
Pozwól użytkownikom wybierać obrazy z galerii lub robić zdjęcia!
Instalacja
npx expo install expo-image-pickerKonfiguracja uprawnień (app.json)
{
"expo": {
"plugins": [
[
"expo-image-picker",
{
"photosPermission": "Aplikacja wymaga dostępu do zdjęć",
"cameraPermission": "Aplikacja wymaga dostępu do kamery"
}
]
]
}
}Wybór z galerii
import * as ImagePicker from 'expo-image-picker';
function PhotoSelector() {
const [image, setImage] = useState<string | null>(null);
const pickImage = async () => {
// Sprawdź uprawnienia
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (status !== 'granted') {
Alert.alert('Błąd', 'Brak uprawnień do galerii');
return;
}
// Otwórz picker
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ['images'],
allowsEditing: true,
aspect: [4, 3],
quality: 0.8,
});
if (!result.canceled && result.assets[0]) {
setImage(result.assets[0].uri);
}
};
return (
<View style={styles.container}>
<Pressable style={styles.button} onPress={pickImage}>
<Text>Wybierz zdjęcie</Text>
</Pressable>
{image && (
<Image source={{ uri: image }} style={styles.preview} />
)}
</View>
);
}Robienie zdjęcia
const takePhoto = async () => {
const { status } = await ImagePicker.requestCameraPermissionsAsync();
if (status !== 'granted') {
Alert.alert('Błąd', 'Brak uprawnień do kamery');
return;
}
const result = await ImagePicker.launchCameraAsync({
allowsEditing: true,
aspect: [1, 1],
quality: 0.9,
});
if (!result.canceled && result.assets[0]) {
setImage(result.assets[0].uri);
}
};Opcje ImagePicker
const result = await ImagePicker.launchImageLibraryAsync({
// Typy mediów
mediaTypes: ['images', 'videos'], // 'images', 'videos', 'livePhotos' (iOS)
// Edycja
allowsEditing: true, // Pozwól na przycinanie
aspect: [16, 9], // Proporcje (tylko z allowsEditing)
// Jakość
quality: 1, // 0-1 (1 = najwyższa)
// Wiele obrazów
allowsMultipleSelection: true,
// Base64
base64: false, // Zwróć też jako base64
// EXIF
exif: true, // Metadane zdjęcia
});
// Wynik
if (!result.canceled) {
result.assets.forEach((asset) => {
console.log('URI:', asset.uri);
console.log('Width:', asset.width);
console.log('Height:', asset.height);
console.log('Type:', asset.type); // 'image' lub 'video'
console.log('File size:', asset.fileSize);
console.log('EXIF:', asset.exif);
});
}Komponent wyboru zdjęć
interface ImagePickerButtonProps {
onImageSelected: (uri: string) => void;
}
function ImagePickerButton({ onImageSelected }: ImagePickerButtonProps) {
const showOptions = () => {
Alert.alert(
'Dodaj zdjęcie',
'Wybierz źródło',
[
{ text: 'Aparat', onPress: takePhoto },
{ text: 'Galeria', onPress: pickFromGallery },
{ text: 'Anuluj', style: 'cancel' },
]
);
};
const takePhoto = async () => {
const { status } = await ImagePicker.requestCameraPermissionsAsync();
if (status !== 'granted') return;
const result = await ImagePicker.launchCameraAsync({
allowsEditing: true,
quality: 0.8,
});
if (!result.canceled) {
onImageSelected(result.assets[0].uri);
}
};
const pickFromGallery = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
allowsEditing: true,
quality: 0.8,
});
if (!result.canceled) {
onImageSelected(result.assets[0].uri);
}
};
return (
<Pressable style={styles.button} onPress={showOptions}>
<Ionicons name="camera" size={24} />
<Text>Dodaj zdjęcie</Text>
</Pressable>
);
}expo-image-picker to najprostszy sposób na wybór zdjęć w Expo!
Kod do tej lekcji: App.tsx
import React, { useState } from 'react';
import { View, Text, Pressable, StyleSheet, Alert } from 'react-native';
import { Image } from 'expo-image';
import * as ImagePicker from 'expo-image-picker';
export default function App() {
const [image, setImage] = useState<string | null>(null);
const pickFromGallery = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
quality: 0.8,
});
if (!result.canceled) {
setImage(result.assets[0].uri);
}
};
const takePhoto = async () => {
const result = await ImagePicker.launchCameraAsync({
allowsEditing: true,
quality: 0.8,
});
if (!result.canceled) {
setImage(result.assets[0].uri);
}
};
const showOptions = () => {
// TODO: wywołaj Alert.alert z tytułem 'Dodaj zdjęcie' i trzema przyciskami:
// - { text: 'Aparat', onPress: takePhoto }
// - { text: 'Galeria', onPress: pickFromGallery }
// - { text: 'Anuluj', style: 'cancel' }
};
return (
<View style={styles.container}>
<Pressable style={styles.button} onPress={showOptions}>
<Text style={styles.buttonText}>Dodaj zdjęcie</Text>
</Pressable>
{image && <Image source={{ uri: image }} style={styles.preview} />}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
justifyContent: 'center',
backgroundColor: '#1a5276',
},
button: {
backgroundColor: '#2980b9',
padding: 14,
borderRadius: 8,
alignItems: 'center',
},
buttonText: { color: '#fff', fontSize: 16, fontWeight: '600' },
preview: { width: '100%', height: 250, borderRadius: 12, marginTop: 20 },
});Hasła z dokumentacji w tej lekcji
Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Która funkcja otwiera galerię zdjęć?
2. Która opcja pozwala wybrać wiele zdjęć?
Zadania praktyczne w grze
- Klikanie w kolejności
Kliknij elementy konfiguracji image picker, która pozwala wybrać tylko zdjęcia:
- Edytor kodu
Uzupełnij kod z Alert i ImagePicker.