[필터 앱 만들기] 3. 세로 이미지가 가로로 회전되는 문제 해결하기

이대현·2024년 3월 31일
0

iOS

목록 보기
8/9

1. 문제 상황

필터 앱을 만들고 있다. 그런데 세로로 찍은 이미지들에 LUT 필터를 적용하려고 사진을 불러오면, 아래처럼 이미지가 가로로 회전되는 문제가 발생했다. 정말 가지가지 ~

  • 움짤 매우 느림 주의 🥲

2. 원인

UIImage.Orientation

enum Orientation : Int, @unchecked Sendable

developer.apple 설명을 보면 왜 휴대폰을 제대로 세로로 들고 찍었을 때 방향이 right 로 설정되어 있는지 알 수 있다.

iOS 장치 카메라는 항상 카메라 센서의 기본 가로 방향에서 픽셀 데이터를 인코딩한다. 때문에 UIImage가 세로 방향으로 찍은 사진을 로드할 때, 이미지 데이터를 표시하기 전에 자동으로 90° 회전을 적용하여 UIImage.Orientation이 right로 표시되는 것이다.

즉, 모든 이미지 파일은 원본 이미지와 방향 정보를 가지고 있고, 이미지를 보여주는 소프트웨어가 이미지 처리 방법에 따라 원본 이미지를 회전시켜 보여준다는 것 같다. UIImage에 세로로 찍은 사진을 올려도, 방향이 가로가 아니라 세로로 잘 올라가는 이유가 UIImage.Orientation 덕분인 것이다.

👿 그런데, 문제는 지난 글에서 공부했던 CGImage에 있다.

우리가 LUT를 적용하기 위해서는 픽셀 데이터를 조작하기 위해 UIImage를 CGImage로 변환해야하는데, CGImage에는 Orientation 정보가 없다. CGImage는 기본적으로 원본 이미지를 비트맵으로 그려줘서 방향은 신경을 써주지 않는 것이다.

그래서 CGImage로부터 이미지를 처리하고 다시 UIImage(cgImg: cgimg)를 변환해 얻었을 때 imageView 에서 보이는 이미지의 방향이 기존과 달라지게 되는 것이다.


3. 해결방법

해결방법은 다양할 수 있다. UIImage를 초기화할 때 기존 이미지 방향을 기억해놨다가 입력해 줄 수 있고, 아니면 그냥 UIImage를 특정한 각도만큼 회전시키는 메서드를 extension으로 만들어두기도 한다.

나는 이번 프로젝트에서 두 번째 방법을 사용했고, rotate(radians:) 만들어 extension으로 빼두었다. 이유는 앞으로 쓸 일이 자주 있을 것 같아서...

extension UIImage {
    func rotate(radians: Float) -> UIImage? {
      // ...
        return newImage
    }
}

4. 그 외, iOS의 EXIF

찍은 장소, 시간, 노출값 등 이미지 정보를 잠깐 보여주는 기능을 만들고 싶다. 이런 메타데이터는 표준으로 정해진 형식이 있다. 그 형식이 바로 EXIF, Exchangable Image File Format으로 우리말로는 교환 이미지 파일 형식이라고 한다.

웹, 모바일, 디지털 카메라 등 플랫폼을 불문하고 이미지를 처리하는 경우에는 이 EXIF에 접근할 수 있도록 API를 제공한다.

iOS에선 두 가지 방법을 쓰는 것 같은데,

  1. CGImageProperties에서 EXIF Dictionary Key를 이용하는 방법

  2. PHPicker에서 가져온 이미지의 PHAsset을 이용해 메타데이터에 접근하는 방법 (iOS14 이상)

다음번에는 이 기능을 적용하고 포스팅 해 볼 예정이다.

profile
삽질의 기록들 👨‍💻

0개의 댓글