일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- node
- Animation
- Koin
- MotionLayout
- list
- SwiftUI Tutorial
- databinding
- MediaSession
- 동영상
- SWIFTUI
- node.js
- rx
- liveData
- RxKotlin
- paging
- Reactive
- PagingLib
- 테스트 자동화
- mvvm
- GCP
- android13
- Observable
- junit
- Android
- 인앱결제
- google play
- mysql
- Android 13
- MediaPlayer
- Kotlin
- Today
- Total
봄날은 갔다. 이제 그 정신으로 공부하자
android Bitmap과 함께하는 즐거운 시간 2번째 본문
지난번 글에서 이미지 정보를 읽어올 때 ExifInterface를 사용해서 정보를 읽어오라고 글을 작성하였는데 이미지 정보는 단말의 MediaStore DB에서도 읽어올 수 있습니다.
이번 글에서는 MediaStore DB와 ExifInterface에서 사진 정보를 읽어오는 방법에 대해 설명하도록 하겠습니다.
우선 MediaStore DB부터
MediaStore DB는 대략 아래와 같은 정보를 읽어올 수 있습니다.
아래는 의미 있어보이는 컬럼만 정리한 것으로 삼성 갤럭시 노트10+를 기준으로 55개의 컬럼을 가지고 있습니다.
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DATA,
MediaStore.Images.Media.ORIENTATION,
MediaStore.Images.Media.WIDTH,
MediaStore.Images.Media.HEIGHT,
MediaStore.Images.Media.RESOLUTION,
MediaStore.Images.Media.ISO,
MediaStore.Images.Media.DATE_TAKEN,
MediaStore.Images.Media.DATE_ADDED,
MediaStore.Images.Media.DATE_MODIFIED
MediaStore의 Cursor를 통해 값을 읽어보면 아래와 같은 정보가 보여집니다.
ID: 139, orientation: 0, resolution: 4032×3024, iso: 250, duration: null, exposureTime: 0.016..
ID: 138, orientation: 0, resolution: 4032×3024, iso: 500, duration: null, exposureTime: 0.025
ID: 137, orientation: 0, resolution: 4032×3024, iso: 160, duration: null, exposureTime: 0.0083..
ID: 136, orientation: 90, resolution: 4032×3024, iso: 125, duration: null, exposureTime: 0.0083..
ID: 135, orientation: 90, resolution: 4032×3024, iso: 160, duration: null, exposureTime: 0.025
* orientation이 0, 180은 가로로 촬영된 사진이며 90, 270이면 세로로 촬영된 사진 입니다.
orientation 0이 가장 기본이되는 가로 사진이며 단말을 세워서 찍으면 90 입니다.
위는 해당 단말기에서 찍은 사진으로 대략적인 정보가 잘 저장되어 있지만 다운로드 받거나 캡쳐한 사진의 정보는 이것과는 조금 다르게 보여집니다. 다운로드 받거나 캡쳐한 사진은 아래와 같이 resolution 정보를 제외하고 ISO, 노출 시간 등의 정보가 DB에 저장되어 있지 않습니다.
당연한 거겠죠…
ID: 124, orientation: null, resolution: 378×504, iso: null, duration: null, exposureTime: null
ID: 102, orientation: null, resolution: 1080×2280, iso: null, duration: null, exposureTime: null
ID: 101, orientation: null, resolution: 1080×2280, iso: null, duration: null, exposureTime: null
그리고 또 추가로 차이가 있다면 DATE 정보가 서로 상이 합니다.
먼저 단말에서 찍은 사진은 날짜 관련된 3 컬럼(DATE_TAKEN, DATE_ADDED, DATE_MODIFIED) 모두 시간이 정상적으로 입력되어 있는데 비해 다운로드 받거나 캡쳐한 사진은 DATE_TAKEN 값은 null이고 나머지 두개 값만 DATE_ADDED, DATE_MODIFIED 입력되어 있습니다.
// 단말기에서 찍은 사진의 DATE
ID: 139, dateTaken: 1613726554000, dateAdded: 1613726555, dateModified: 1613726555
ID: 138, dateTaken: 1613726540000, dateAdded: 1613726541, dateModified: 1613726541
ID: 137, dateTaken: 1613726530000, dateAdded: 1613726531, dateModified: 1613726531
// 다운로드 받거나 캡쳐한 사진의 DATE
ID: 124, dateTaken: null, dateAdded: 1612487826, dateModified: 1612487826
ID: 102, dateTaken: null, dateAdded: 1612420248, dateModified: 1612420248
ID: 101, dateTaken: null, dateAdded: 1612420073, dateModified: 1612420073
* 참고로 DATE_TAKEN 값은 milli second 단위까지 기록되고 DATE_ADDED, DATE_MODIFIED는 second 단위까지만 기록됩니다.
그렇므로 MediaStore DB에서 값을 읽어올 때 정렬값으로 DATE_TAKEN을 사용하게 되면 단말기에서 생성한 사진이 아닌 다운로드 받거나 캡쳐한 사진은 전부 DATE 값이 null이라서 맨 뒤에 나오게 됩니다.
그러므로 최신 순으로 보고자 한다면 DATE_TAKEN이 아닌 다른 값 DATE_ADDED나 DATE_MODIFIED 그도 아니면 _ID를 정렬값을 사용해야 합니다.
MediaStore DB 정보는 여기까지 알아보고 이제 ExifInterface를 통해 읽어 올 수 있는 정보들에 대해 살펴보도록 하겠습니다.
// ExifInterface를 통해 읽어온 단말기에서 찍은 사진의 정보
ID: 139, orientation: 1, copyright: null, dateTime: 2021:02:19 18:22:34, make: samsung, model: SM-N976N, brightness: 0, aperture: 2.52, contrast: 0
ID: 138, orientation: 1, copyright: null, dateTime: 2021:02:19 18:22:20, make: samsung, model: SM-N976N, brightness: 0, aperture: 2.52, contrast: 0
ID: 137, orientation: 1, copyright: null, dateTime: 2021:02:19 18:22:10, make: samsung, model: SM-N976N, brightness: 0, aperture: 2.52, contrast: 0
ID: 136, orientation: 6, copyright: null, dateTime: 2021:02:19 18:22:00, make: samsung, model: SM-N976N, brightness: 0, aperture: 2.52, contrast: 0
// ExifInterface를 통해 읽어온 다운받거나 캡쳐한 사진의 정보
ID: 124, orientation: 0, copyright: null, dateTime: null, make: null, model: null, brightness: 0, aperture: 0.0, contrast: 0
ID: 102, orientation: 0, copyright: null, dateTime: null, make: null, model: null, brightness: 0, aperture: 0.0, contrast: 0
D: 101, orientation: 0, copyright: null, dateTime: null, make: null, model: null, brightness: 0, aperture: 0.0, contrast: 0
orientation값은 아래와 같이 정의되어 있습니다.
public static final int ORIENTATION_UNDEFINED = 0;
public static final int ORIENTATION_NORMAL = 1;
public static final int ORIENTATION_FLIP_HORIZONTAL = 2; // left right reversed mirror
public static final int ORIENTATION_ROTATE_180 = 3;
public static final int ORIENTATION_FLIP_VERTICAL = 4; // upside down mirror
public static final int ORIENTATION_TRANSPOSE = 5;
public static final int ORIENTATION_ROTATE_90 = 6; // rotate 90 cw to right it
public static final int ORIENTATION_TRANSVERSE = 7;
public static final int ORIENTATION_ROTATE_270 = 8; // rotate 270 to right it
위 정보를 보면 단말에서 찍은 사진은 대부분의 단말의 세부 정보까지 잘 저장되어 있지만 다운받거나 캡쳐한 사진의 경우, 아무런 값도 저장되어 있지 않음을 알 수 있습니다.
ExifInterface에는 orientation 정보 외에도 사진을 촬영한 기기의 제조사 및 모델 정보와 조리개 값까지 저장되어 있음을 알 수 있습니다.
정리
개발 시 처음 사진 정보는 MediaStore DB에서 읽어오고 상세보기와 같이 조금 더 추가적인 정보가 필요한 경우에 ExifInterface를 사용하는 방식을 사용한다면 성능 문제 없이 빠르게 사진을 처리할 수 있습니다.
'android Tip' 카테고리의 다른 글
아이콘 클릭 시 종처럼 흔들리는 애니메이션 효과 주기 (0) | 2021.04.07 |
---|---|
android Bitmap과 함께하는 즐거운 시간 3번째 (0) | 2021.03.24 |
android Bitmap과 함께하는 즐거운 시간 (0) | 2021.03.15 |
네트워크 비동기 통신에서 중복 요청 방지 (0) | 2021.03.05 |
android R Scoped Storage 2편 (미디어 저장소에서 이미지를 읽어오자) (0) | 2021.02.11 |