이미지 내에 포함되어 있는 Exif 데이터는 조리개, 셔터속도, 초점 거리, 측광방식, ISO 설정 그리고 출력시 도움을 줄 수 있는 색상 정보등이 들어있다. 이와 더불어 카메라의 모델명, 등록번호, 위치 정보 등 다른 정보도 포함되어 있다.

지오태깅은 웹사이트, 비디오, QR 코드, 이미지 등 다양한 미디어에서 지리적 식별 메타데이터를 추가하는 프로세스를 일컫는다.

이 포스팅에서는 이미지내에 포함되어 있는 지오태깅 메타데이터를 간단히 제거하는 방법에 대해서 살펴본다. 이 포스팅을 읽기전에 이전 Exif와 관련된 포스팅을 먼저 읽고 오시는 것을 권장합니다.

이미지에 포함된 GPS 정보들

위 이미지는 iPhone 14 Pro 기기로 촬영한 heic 포맷 이미지다. 별도 처리 없이 이미내에 포함된 GPS 정보들을 확인하면 고도, 위도,경도 등 개인정보와 연관된 내용들이 포함되어 있다. 사진에 포함된 이런 민감한 정보들을 사용자가 일일이 지워가며 앱 및 서비스를 이용하기는 어렵다.

GPS 정보 제거

ExifInterface에 정의된 GPS와 관련된 태그 목록은 다음과 같다.

val tags = listOf(
    ExifInterface.TAG_GPS_VERSION_ID,
    ExifInterface.TAG_GPS_LATITUDE_REF,
    ExifInterface.TAG_GPS_LATITUDE,
    ExifInterface.TAG_GPS_LONGITUDE_REF,
    ExifInterface.TAG_GPS_LONGITUDE,
    ExifInterface.TAG_GPS_ALTITUDE_REF,
    ExifInterface.TAG_GPS_ALTITUDE,
    ExifInterface.TAG_GPS_TIMESTAMP,
    ExifInterface.TAG_GPS_SATELLITES,
    ExifInterface.TAG_GPS_STATUS,
    ExifInterface.TAG_GPS_MEASURE_MODE,
    ExifInterface.TAG_GPS_DOP,
    ExifInterface.TAG_GPS_SPEED_REF,
    ExifInterface.TAG_GPS_SPEED,
    ExifInterface.TAG_GPS_TRACK_REF,
    ExifInterface.TAG_GPS_TRACK,
    ExifInterface.TAG_GPS_IMG_DIRECTION_REF,
    ExifInterface.TAG_GPS_IMG_DIRECTION,
    ExifInterface.TAG_GPS_MAP_DATUM,
    ExifInterface.TAG_GPS_DEST_LATITUDE_REF,
    ExifInterface.TAG_GPS_DEST_LATITUDE,
    ExifInterface.TAG_GPS_DEST_LONGITUDE_REF,
    ExifInterface.TAG_GPS_DEST_LONGITUDE,
    ExifInterface.TAG_GPS_DEST_BEARING_REF,
    ExifInterface.TAG_GPS_DEST_BEARING,
    ExifInterface.TAG_GPS_DEST_DISTANCE_REF,
    ExifInterface.TAG_GPS_DEST_DISTANCE,
    ExifInterface.TAG_GPS_PROCESSING_METHOD,
    ExifInterface.TAG_GPS_AREA_INFORMATION,
    ExifInterface.TAG_GPS_DATESTAMP,
    ExifInterface.TAG_GPS_DIFFERENTIAL,
    ExifInterface.TAG_GPS_H_POSITIONING_ERROR
)

이 태그들을 반복문으로 순회하며 Exif 속성값을 제거하면 된다.

val exif:ExifInterface = ...

tags.forEach { tag-> 
    exif.setAttribute(tag, null) // 태그와 관련된 속성 제거
}
exif.saveAttributes() // 저장

리플렉션을 활용한 GPS 정보 제거

또 다른 방법으로는 리플렉션을 통해 ExifInterface에서 태그 필드들을 가져 온 뒤 제거 하는 것이다.

val exif = ...
for (field in ExifInterface::class.java.fields) { // ExifInterface에 정의 된 필드 목록 순회
    val name = field.name // 필드 이름
    if (!name.startsWith("TAG_")) { // 필드 상수 이름은 항상 TAG_로 시작한다. 그렇지 않으면 통과
        continue
    }
    val tag: String = try {
        field?.get(null) as? String // 필드 상수 값을 가져 온다.
    } catch (e: Exception) {
        continue 
    } ?: continue

    if (tag.startsWith("GPS")) { // GPS와 관련된 태그명은 GPS로 시작한다.
        exif.setAttribute(tag, null) // GPS와 연관된 속성 값은 null로 초기화 한다.
    }
}
exif.saveAttributes() // 저장

리플렉션을 활용하면 첫번째 방법보다 코드 라인수는 줄어들고, 좀 더 유연하게 다양한 케이스에 대해서 활용할 수 있다. 하지만 여러가지 상황에서 예외가 발생할 수 있기 때문에 이에 대한 위험요소 인지와 예외처리는 필수다.

카테고리: etc

0개의 댓글

답글 남기기

Avatar placeholder

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.