Перейти к содержимому

16. Изображения и медиа

Работа с изображениями, видео, камерой и галереей в React Native.

import { Image } from 'react-native';
// Локальный файл
<Image source={require('./assets/logo.png')} style={{ width: 200, height: 200 }} />
// Удалённый URL (размеры обязательны!)
<Image
source={{ uri: 'https://example.com/photo.jpg' }}
style={{ width: 200, height: 200 }}
resizeMode="cover" // cover | contain | stretch | center
/>
Окно терминала
npx expo install expo-image
import { Image } from 'expo-image';
<Image
source={imageUrl}
style={{ width: 300, height: 200 }}
contentFit="cover"
transition={200} // Плавное появление
cachePolicy="memory-disk" // Кеширование
placeholder={{ blurhash: 'LKO2:N%2Tw=w]~RBVZRi};RPxuwH' }} // Блюрхэш
/>

Преимущества expo-image:

  • Кеширование из коробки
  • BlurHash / ThumbHash placeholder
  • Лучшая производительность
  • Поддержка SVG, GIF, WebP, AVIF
Окно терминала
npx expo install expo-image-picker
import * as ImagePicker from 'expo-image-picker';
// Выбрать из галереи
const pickImage = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
aspect: [4, 3],
quality: 0.8,
});
if (!result.canceled) {
setImage(result.assets[0].uri);
}
};
// Сделать фото камерой
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) {
setImage(result.assets[0].uri);
}
};
Окно терминала
npx expo install expo-camera
import { CameraView, useCameraPermissions } from 'expo-camera';
function CameraScreen() {
const [permission, requestPermission] = useCameraPermissions();
const cameraRef = useRef(null);
if (!permission?.granted) {
return <Button title="Разрешить камеру" onPress={requestPermission} />;
}
const takePicture = async () => {
const photo = await cameraRef.current.takePictureAsync({ quality: 0.8 });
console.log(photo.uri);
};
return (
<CameraView ref={cameraRef} style={{ flex: 1 }} facing="back">
<TouchableOpacity onPress={takePicture} style={styles.captureButton} />
</CameraView>
);
}
Окно терминала
npx expo install expo-av
import { Video, ResizeMode } from 'expo-av';
<Video
source={{ uri: 'https://example.com/video.mp4' }}
style={{ width: '100%', height: 200 }}
resizeMode={ResizeMode.CONTAIN}
useNativeControls
isLooping
shouldPlay={false}
onPlaybackStatusUpdate={status => {
if (status.isLoaded) {
console.log('Position:', status.positionMillis);
}
}}
/>
const uploadImage = async (uri: string) => {
const formData = new FormData();
formData.append('file', {
uri,
type: 'image/jpeg',
name: 'photo.jpg',
} as any);
const response = await fetch('https://api.example.com/upload', {
method: 'POST',
body: formData,
headers: { 'Content-Type': 'multipart/form-data' },
});
return response.json();
};