Expo Image Picker
Профайл зураг солих, нийтлэлд зураг хавсаргах, баримт бичиг илгээх — энэ бүхэнд image picker хэрэгтэй. expo-image-picker package нь галерейгаас зураг сонгох болон камераас шууд зураг авах хоёр функцийг нэг дор өгдөг. Өмнөх хичээлийн expo-camera-с ялгаатай нь — энэ нь хэрэглэгчийн туршлагад нийцсэн бэлэн UI-тай ирдэг.
expo-image-picker суулгах
npx expo install expo-image-picker
Суулгасны дараа галерей болон камерын зөвшөөрлийг useMediaLibraryPermissions ба useCameraPermissions hook-уудаар авна.
Галерейгаас зураг сонгох
launchImageLibraryAsync() функц нь утасны зургийн галерейг нээдэг. Хэрэглэгч зураг сонгоод гарч ирэх үед result объект буцаана:
import { useState } from "react";
import * as ImagePicker from "expo-image-picker";
import { View, Text, Image, TouchableOpacity, StyleSheet } from "react-native";
export default function AvatarPicker() {
const [image, setImage] = useState(null);
const pickImage = async () => {
// Зөвшөөрөл авах
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (status !== "granted") {
alert("Галерей ашиглахад зөвшөөрөл шаардлагатай");
return;
}
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true, // Хэрэглэгч зургийг тайрч болно
aspect: [1, 1], // Дөрвөлжин crop
quality: 0.8, // 0–1 чанарын хэмжэ
});
if (!result.canceled) {
setImage(result.assets[0].uri);
}
};
return (
<View style={styles.container}>
<TouchableOpacity style={styles.avatarWrap} onPress={pickImage}>
{image ? (
<Image source={{ uri: image }} style={styles.avatar} />
) : (
<View style={styles.placeholder}>
<Text style={styles.placeholderText}>📷</Text>
<Text style={styles.placeholderLabel}>Зураг сонгох</Text>
</View>
)}
</TouchableOpacity>
{image && (
<TouchableOpacity style={styles.btn} onPress={pickImage}>
<Text style={styles.btnText}>Зураг солих</Text>
</TouchableOpacity>
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#0b1120",
gap: 20,
},
avatarWrap: {
width: 120,
height: 120,
borderRadius: 60,
overflow: "hidden",
borderWidth: 2,
borderColor: "#22d3ee",
},
avatar: {
width: "100%",
height: "100%",
},
placeholder: {
flex: 1,
backgroundColor: "#0f172a",
justifyContent: "center",
alignItems: "center",
gap: 4,
},
placeholderText: {
fontSize: 28,
},
placeholderLabel: {
color: "#94a3b8",
fontSize: 11,
},
btn: {
backgroundColor: "#1e293b",
paddingHorizontal: 20,
paddingVertical: 10,
borderRadius: 8,
borderWidth: 1,
borderColor: "#22d3ee",
},
btnText: {
color: "#22d3ee",
fontWeight: "600",
fontSize: 14,
},
});
result.canceled boolean — хэрэглэгч хаасан бол true. result.assets[0].uri нь сонгосон зургийн локал замыг өгнө.
Камераас зураг авах
launchCameraAsync() нь утасны камерыг нээдэг. Галерейтэй адил API, зөвхөн функцийн нэр өөр:
import { useState } from "react";
import * as ImagePicker from "expo-image-picker";
import {
View,
Text,
Image,
TouchableOpacity,
StyleSheet,
Alert,
} from "react-native";
export default function PhotoCapture() {
const [photo, setPhoto] = useState(null);
const takePhoto = async () => {
const { status } = await ImagePicker.requestCameraPermissionsAsync();
if (status !== "granted") {
Alert.alert("Зөвшөөрөл", "Камер ашиглахад зөвшөөрөл шаардлагатай");
return;
}
const result = await ImagePicker.launchCameraAsync({
allowsEditing: false,
quality: 1,
});
if (!result.canceled) {
setPhoto(result.assets[0]);
}
};
return (
<View style={styles.container}>
{photo ? (
<View style={styles.previewWrap}>
<Image source={{ uri: photo.uri }} style={styles.preview} />
<Text style={styles.meta}>
{Math.round(photo.width)} × {Math.round(photo.height)} px
</Text>
<TouchableOpacity style={styles.btn} onPress={takePhoto}>
<Text style={styles.btnText}>Дахин авах</Text>
</TouchableOpacity>
</View>
) : (
<TouchableOpacity style={styles.cameraBtn} onPress={takePhoto}>
<Text style={styles.cameraIcon}>📸</Text>
<Text style={styles.cameraLabel}>Зураг авах</Text>
</TouchableOpacity>
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#0b1120",
},
cameraBtn: {
backgroundColor: "#0f172a",
borderRadius: 16,
padding: 32,
alignItems: "center",
gap: 12,
borderWidth: 1,
borderColor: "#1e293b",
borderStyle: "dashed",
},
cameraIcon: {
fontSize: 40,
},
cameraLabel: {
color: "#94a3b8",
fontSize: 14,
},
previewWrap: {
alignItems: "center",
gap: 12,
padding: 20,
},
preview: {
width: 280,
height: 280,
borderRadius: 12,
},
meta: {
color: "#475569",
fontSize: 12,
},
btn: {
backgroundColor: "#22d3ee",
paddingHorizontal: 24,
paddingVertical: 10,
borderRadius: 8,
},
btnText: {
color: "#0b1120",
fontWeight: "700",
},
});
Галерей эсвэл камер — хэрэглэгчид сонгуулах
Жинхэнэ апп-д хоёуланг санал болгох нь хамгийн сайн туршлага:
import * as ImagePicker from "expo-image-picker";
import { Alert } from "react-native";
const selectImage = (onSelect) => {
Alert.alert("Зураг сонгох", "", [
{
text: "Галерейгаас",
onPress: async () => {
const { status } =
await ImagePicker.requestMediaLibraryPermissionsAsync();
if (status !== "granted") return;
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
aspect: [1, 1],
quality: 0.8,
});
if (!result.canceled) onSelect(result.assets[0].uri);
},
},
{
text: "Камераас",
onPress: async () => {
const { status } = await ImagePicker.requestCameraPermissionsAsync();
if (status !== "granted") return;
const result = await ImagePicker.launchCameraAsync({
allowsEditing: true,
aspect: [1, 1],
quality: 0.8,
});
if (!result.canceled) onSelect(result.assets[0].uri);
},
},
{ text: "Болих", style: "cancel" },
]);
};
// Хэрэглэх:
// selectImage((uri) => setAvatarUri(uri));
Alert.alert дахь ActionSheet загвар нь iOS-д native action sheet болж харагддаг. Хоёр мөр кодоор хэрэглэгчид сонголт өгөх боломжтой — энэ ч мөн React Native-н давуу тал!
Дараагийн хичээлд:
Expo Location — GPS ашиглан хэрэглэгчийн байршил авах, координатыг хаягт хөрвүүлэх геолокаци функц сурна.