이전 블로그에서 갤러리 & 앨범에서 이미지 가져오는 방법에 대해 알아 보았습니다.
2024.09.21 - [리액트(React)] - [React Native] 갤러리&앨범 이미지 가져오기
이번에는 좀 더 나아가서 이미지에서 위치정보를 가져오는 방법에 대해 알아보고자 합니다.
핸드폰(삼성 기준) 갤러리앱에서 이미지를 선택하고 상세보기를 보면 사진관련 다양한 정보들을 확인할 수 있습니다.
아래 이미지는 광화문에서 찍은 사진인데 촬영한 날짜, 시간, 핸드폰 기종, 해상도, 카메라 셋팅값, 파일용량, 저장위치, 파일명 등 다양한 정보를 확인 가능합니다. 여기에 위치정보도 같이 있어서 주소지 정보와 지도상 위치도 확인 가능합니다.
이러한 정보의 기준 포맷은 무엇일까요?
혹시 Exif 라는 이미지 파일포맷을 들어 보신적 있나요?
- Exif 란 ?
- EXchangable Image File format 의 약자
- 디지털 카메라에서 이용되는 이미지 파일 포맷으로 JPEG, TIFF 6.0과 RIFF, WAV 파일 포맷에서 이용되며 사진에 대한 정보를 포함하는 메타데이터를 추가로 가지고 있음
- Exif Viewer
- Exif 파일 포맷의 이미지의 상세 정보를 확인할 수 있는 뷰어로 아래 사이트 참고
- https://exif.tools/
EXIF / File Metadata Viewer
exif.tools
위의 Exif tools를 사용하여 제가 샘플로 올린 광화문 사진의 정보를 보면 다음과 같습니다.
많은 Metadata중에서 GPS 관련 정보도 포함되어 있습니다.
앱 개발시 이미지를 가져오는 React-native 패키지 종류는 다음과 같습니다.
- react-native-image-picker
- expo-image-picker
그럼 두 패키지의 차이점에 대해 좀 더 상세히 알아보겠습니다.
- 차이점 비교
항목 | react-native-image-picker | expo-image-picker |
설치 및 설정 | 네이티브 모듈 설정 필요 (iOS: `Info.plist`, Android: `Manifest`) |
Expo 프로젝트에서 간단히 설치 가능, 추가 설정 불필요 |
플랫폼 호환성 | React Native CLI 기반 프로젝트 (iOS, Android) | Expo 기반 프로젝트 (iOS, Android) |
사용자 인터페이스 | 커스터마이징 가능, 기본 UI 없음 | 기본 UI 제공, Expo 디자인 가이드라인 준수 |
기능 | 이미지/비디오 선택, 카메라 촬영, 크롭/리사이즈 등 고급 기능 지원 |
이미지/비디오 선택, 크기 조정 및 품질 설정 가능 |
커뮤니티 및 지원 | 널리 사용되지만 업데이트가 느릴 수 있음 | 활발한 커뮤니티와 공식 문서 제공 |
성능 | 네이티브 최적화 가능하지만 설정 복잡 | Expo 환경에 최적화되어 성능 우수 |
- react-native-image-picker 사용법
- 패키지설치 : yarn add react-native-image-picker
- iOS는 추가 설치 : npx pod-install ios
- 코드 예제
import React, { useState } from 'react';
import { View, Button, Image, StyleSheet } from 'react-native';
import { launchImageLibrary } from 'react-native-image-picker';
export default function App() {
const [imageUri, setImageUri] = useState(null);
const pickImage = () => {
const options = {
mediaType: 'photo',
quality: 1,
};
launchImageLibrary(options, (response) => {
if (!response.didCancel && !response.errorCode) {
setImageUri(response.assets[0].uri);
}
});
};
return (
{imageUri && }
);
}
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
image: { width: 200, height: 200 },
});
- expo-image-picker 사용법
- 패키지 설치 : npx expo install expo-image-picker
- 코드예시
import React, { useState } from 'react';
import { View, Button, Image, StyleSheet } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
export default function App() {
const [imageUri, setImageUri] = useState(null);
const pickImage = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
quality: 1,
});
if (!result.canceled) {
setImageUri(result.assets[0].uri);
}
};
return (
{imageUri && }
);
}
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
image: { width: 200, height: 200 },
});
그럼 이렇게만 하면 위치정보를 가져올 수 있을까요??
아닙니다. 이렇게 하면 위치정보를 가져오지 않습니다. 그럼 어떻게 해야할까요??
이부분에 있어서 많은 웹서핑과 github 까지 확인했는데 결국 답은 EXIF 포맷에 있었습니다.
그렇기에 앞에서 EXIF 에 대해 먼저 언급을 한 것 입니다.
Expo의 공식 문서에 나오는 이미지 정보는 다음과 같습니다.
어디에도 위치정보는 없습니다. 즉, exif 값이 null 로 보입니다.
{
"assets": [
{
"assetId": "C166F9F5-B5FE-4501-9531",
"base64": null,
"duration": null,
"exif": null,
"fileName": "IMG.HEIC",
"fileSize": 6018901,
"height": 3025,
"type": "image",
"uri": "file:///data/user/0/host.exp.exponent/cache/cropped1814158652.jpg"
"width": 3024
}
],
"canceled": false
}
그럼 여기서 exif 값이 보이게 셋팅하는 방법입니다. 알고 보면 간단하지만 찾는데 고생(?) 좀 했습니다.
ImagePicker 에서 속성으로 exif 를 추가해주면 됩니다.
👉 exif: true
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ['images'],
allowsEditing: false,
quality: 1,
exif: true,
legacy: true,
});
exif 추가 정보 : 속성 데이터중 location 정보 추출 가능
"Asset info":{
"albumId":"-2075821635",
"creationTime":1741401508375,
"duration":0,
"exif":{
"ApertureValue":1.69,
"BrightnessValue":6.37,
"ColorSpace":1,
"Compression":6,
"DateTime":"2025:03:08 11:38:28",
"DateTimeDigitized":"2025:03:08 11:38:28",
"DateTimeOriginal":"2025:03:08 11:38:28",
"DigitalZoomRatio":1,
"ExifVersion":"0220",
"ExposureBiasValue":0,
"ExposureMode":0,
"ExposureProgram":2,
"ExposureTime":0.005555555555555556,
"FNumber":1.8,
"Flash":0,
"FlashpixVersion":"0100",
"FocalLength":6.4,
"FocalLengthIn35mmFilm":23,
"GPSLatitudeRef":"N",
"GPSLongitudeRef":"E",
"ISOSpeedRatings":20,
"ImageLength":3000,
"ImageUniqueID":"L40XLOD00NM",
"ImageWidth":4000,
"JPEGInterchangeFormat":996,
"JPEGInterchangeFormatLength":42910,
"LightSource":0,
"Make":"samsung",
"MaxApertureValue":1.69,
"MeteringMode":3,
"Model":"SM-S908N",
"Orientation":6,
"PixelXDimension":4000,
"PixelYDimension":3000,
"ResolutionUnit":2,
"SceneCaptureType":0,
"ShutterSpeedValue":0.005555555555555556,
"Software":"S908NKSS6EYB1",
"SubSecTime":"375",
"SubSecTimeDigitized":"375",
"SubSecTimeOriginal":"375",
"ThumbnailImageLength":384,
"ThumbnailImageWidth":512,
"WhiteBalance":0,
"XResolution":72,
"YCbCrPositioning":1,
"YResolution":72
},
"filename":"24047e24-8db0-4bb3-8845-c001747fdd93.jpeg",
"height":4000,
"id":"1000010460",
"localUri":"file:///storage/emulated/0/DCIM/24047e24-8db0-4bb3-8845-c001747fdd93.jpeg",
"location":{
"latitude":35.8273183,
"longitude":128.6223007
},
"mediaType":"photo",
"modificationTime":1741516879000,
"uri":"file:///storage/emulated/0/DCIM/24047e24-8db0-4bb3-8845-c001747fdd93.jpeg",
"width":3000
}
이렇게 원하는 위치정보를 얻었는데 나머지 한가지 문제는 GPS 위치를 그대로 서비스 할 수 없다는데 있습니다.
물론 지도서비스를 제공하는데는 GPS정보만 있으면 되지만 '주소' 정보가 필요한 경우는 다른 지도 API 를 사용해야 합니다.
이와 같이 하나의 서비스를 제공하는데 있어서 어려움이 많구나를 느끼게 됩니다.
저는 구글 Geocoding API를 추가로 적용하여 주소정보를 가져와서 서비스를 제공했습니다.
다른 분들도 다양한 지도 API를 활용하여 서비스에 적용해보시면 될 것 같습니다.
저희 다소 험난한 과정을 정리해 보았는데 도움이 되셨기를 바랍니다.
'리액트(React)' 카테고리의 다른 글
React Native - tooltip 적용하기 (0) | 2025.05.09 |
---|---|
NoSQL Firebase Realtime Database vs Cloud Firestore 비교하기 (0) | 2025.04.08 |
구글 파이어베이스 스토리지에서 이미지 관리(1) (0) | 2025.01.16 |
파이썬-우편번호API 이용 우편번호 찾기(2) (1) | 2024.12.20 |
리액트 성능최적화 하기 - useMemo, useCallback (1) | 2024.11.17 |