Kurs React Native · Moduł 6: Zdjęcia, kamera i dźwięk

expo-image-picker - Wybór obrazów

3 min czytania ·
W tej lekcji6

Pozwól użytkownikom wybierać obrazy z galerii lub robić zdjęcia!

Instalacja

npx expo install expo-image-picker

Konfiguracja 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. 1. Która funkcja otwiera galerię zdjęć?

  2. 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.

Przydatne artykuły