끄적이는 개발노트
React Native - 이미지 선택 (react-native-image-picker) 본문
React Native Cli 로 어플을 개발하면 사진 앱, 카메라 앱을 실행하는 기능을 제공하지 않는다고 한다.
따라서 라이브러리를 활용해야 하는데 react-native-image-picker 와 react-native-image-crop-picker가 많이 사용된다.
react-native-image-picker는 본인이 느끼기에 가장 베이직한 라이브러리로 카메라와 사진 기능을 제공한다.
https://www.npmjs.com/package/react-native-image-picker/v/4.8.5
react-native-image-picker
A React Native module that allows you to use native UI to select media from the device library or directly from the camera. Latest version: 8.0.0, last published: 13 days ago. Start using react-native-image-picker in your project by running `npm i react-na
www.npmjs.com
react-native-image-crop-picker는 사진을 선택하고 crop할 수 있는 기능을 제공하는 것이 차이점이다.
https://www.npmjs.com/package/react-native-image-crop-picker/v/0.3.1
react-native-image-crop-picker
Select single or multiple images, with cropping option. Latest version: 0.42.0, last published: a month ago. Start using react-native-image-crop-picker in your project by running `npm i react-native-image-crop-picker`. There are 120 other projects in the n
www.npmjs.com
이 중에서 먼저 react-native-image-picker를 살펴본다.
1. 설치
npm install react-native-image-picker
#or
yarn add react-native-image-picker
2. 권한
android의 경우 기본 권한 설정을 할 필요가 없지만, saveToPhotos 옵션을 사용하기 위해서는 WRITE_EXTERNAL_STORAGE 권한을 설정해야 한다.
파일은 android/app/src/main/AndroidManifest.xml 이다.
// AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<!-- 추가 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
3. 옵션
- mediaType : "photo" | "video" | "mixed" 말 그대로 미디어의 타입
- maxWidth : 최대 너비
- maxHeight : 최대 높이
- quality : 이미지 품질(0∽1)
- includeBase64 : 이미지의 base64 문자열을 생성
- cameraType : "back" | "front" 카메라일 경우 전면, 후면 카메라
- saveToPhotos : 카메라일 경우, 촬영한 사진을 저장 여부
이 외에도 몇가지 옵션들이 존재하는데 이는 공식문서를 참고하면 된다.
4. 코드 (갤러리에서 불러오기, launchImageLibrary)
// test2.tsx
import CustomText from '@/components/text';
import {Test2Props} from '@/types/stack';
import {Button, Image, View} from 'react-native';
import {SafeAreaView} from 'react-native-safe-area-context';
import {launchImageLibrary} from 'react-native-image-picker';
import {useState} from 'react';
const Test2Screen = ({navigation}: Test2Props) => {
const [uri, setUri] = useState<string>('');
const onChoosePhoto = async () => {
const result = await launchImageLibrary({
mediaType: 'photo',
quality: 0.9,
});
if (result.didCancel) {
console.log('유저 캔슬');
} else if (result.errorMessage) {
console.error('에러 :' + result.errorMessage);
} else {
setUri(result.assets![0].uri!);
}
};
return (
<SafeAreaView className="flex-1">
<View className="w-full h-full flex justify-center items-center bg-white">
<CustomText className="text-success text-xl" children="테스트 화면" />
<Button title="갤러리" onPress={onChoosePhoto} />
<Image source={{uri: uri}} width={300} height={300} />
</View>
</SafeAreaView>
);
};
export default Test2Screen;
5. 코드 (카메라 촬영, launchCamera)
// test2.tsx
import CustomText from '@/components/text';
import {Test2Props} from '@/types/stack';
import {Button, Image, View} from 'react-native';
import {SafeAreaView} from 'react-native-safe-area-context';
import {launchCamera, launchImageLibrary} from 'react-native-image-picker';
import {useState} from 'react';
const Test2Screen = ({navigation}: Test2Props) => {
const [uri, setUri] = useState<string>('');
const onTakePhoto = async () => {
const result = await launchCamera({
saveToPhotos: true,
mediaType: 'photo',
cameraType: 'back',
quality: 0.9,
});
if (result.didCancel) {
console.log('유저 캔슬');
} else if (result.errorMessage) {
console.error('에러 :' + result.errorMessage);
} else {
setUri(result.assets![0].uri!);
}
};
return (
<SafeAreaView className="flex-1">
<View className="w-full h-full flex justify-center items-center bg-white">
<CustomText className="text-success text-xl" children="테스트 화면" />
<Button title="촬영" onPress={onTakePhoto} />
<Image source={{uri: uri}} width={300} height={300} />
</View>
</SafeAreaView>
);
};
export default Test2Screen;
6. 실행
이렇게 실행한 결과는 assets에 배열 형태로 담겨져 있다. 여러 개를 선택했을 경우 각각 처리를 해주면 되는데 해당 assets의 객체를 일부 살펴본다.
- uri : 캐시 저장소의 파일. 해당 uri를 통해 로컬스토리지에 저장, 공유, 외부 스토리지 저장 등을 활용하면 된다.
- base64 : 이미지의 base64 문자열
- width : 너비
- height : 높이
- type : 타입
- fileSize : 파일 사이즈
- fileName : 파일명
실행해보면 아래와 같이 갤러리에서 선택, 카메라 촬영을 통한 image picker와 해당 uri를 통해 이미지 띄우기가 잘 실행된 것을 확인할 수 있다.
'React Native' 카테고리의 다른 글
React Native - 스크린샷 활용 (1) 화면 캡처 (react-native-view-shot) (3) | 2025.02.17 |
---|---|
React Native - 이미지 선택 (react-native-image-crop-picker) (0) | 2025.02.14 |
React Native - Bottom Sheet (0) | 2025.02.12 |
React Native - Hardware 뒤로 가기 버튼으로 어플 종료 (0) | 2025.02.11 |
React Native - Toast Message (0) | 2025.02.11 |