[필터 앱 만들기] 2. iOS에서 픽셀의 RGB 값을 가져오는 방법

이대현·2024년 3월 31일
0

iOS

목록 보기
7/9

필터 앱을 만들기 위해, LUT(필터 데이터)를 원본 이미지에 적용하는 함수에 대한 수도코드를 아래처럼 짜보았다.

1. 소스 이미지(srcImage)LUT 이미지(lutImage)를 불러온다.
2. 소스 이미지와 LUT 이미지의 비트맵 형식을 확인한다.
3. 소스 이미지의 각 픽셀에 대해 반복하며 다음을 수행한다:
   - **픽셀의 RGB 값을 가져온다.**
   - LUT 이미지에서 해당 RGB 값을 찾아 변환된 RGB 값을 가져온다.
   - 변환된 RGB 값을 가진 새로운 픽셀을 생성한다.
   - 새로운 픽셀을 변환된 이미지([newImage])에 추가한다.
4. 변환된 이미지([newImage])를 저장하거나 사용한다.

즉, 나는 이미지에 대해 공부해야했고, iOS 환경에서는 이미지 비트맵에 어떻게 접근할 수 있는지에 대해 공부해야 했다.

iOS에서는 일반적으로 Core Graphics나 Core Image와 같은 시스템 프레임워크를 사용하여 이미지 처리를 수행한다. 나는 Low한 환경에서 직접 LUT의 비트맵 데이터를 다룰 것이기 때문에, Core Graphics를 사용했다.

우선 이미지에 대해 간단히 공부했다.

1. 이미지 표현 방식

이미지 표현 방식에는 비트맵(Bitmap)과 벡터(Vector)방식이 있다.

Bitmap

  • 이미지를 구성하는 각 픽셀을 행렬로 표현하는 방식이며, 각 픽셀은 색상 정보를 담고 있다.
  • png, jpg, gif
  • 주로 언제 사용?
    • 주로 사진, 다양한 색상 그라디언트가 필요한 이미지 ex) 스플래시 이미지
    • 하지만 사이즈가 커질수록 용량도 무거워진다.

Vector

  • 점, 선, 면에 대한 수학적 연산으로 이루어진 이미지
  • pdf, ai, swf
  • 주로 언제 사용?
    • 주로 많지 않은 색으로 구성되어 있는 단색 이미지 ex) 아이콘, 로고, 도형
    • 벡터 방식은 사이즈를 키워도 용량은 늘어나지 않는다.

나는 비트맵 이미지 프로세싱을 할 것이기 때문에, 픽셀에 대한 학습도 필요했다.

Pixel

이미지를 구성하는 최소단위의 점. rgb 혹은 rgba 정보를 가진다.

  • 대부분의 이미지 형식에서 픽셀은 32비트로 표현된다.
  • 즉, 1픽셀에 4바이트(R, G, B, Alpha 각 1바이트, 총 4개의 채널)가 사용된다. 각 채널은 0부터 255까지의 값을 가지며, 따라서 각 채널은 1바이트(8비트)로 표현된다고할 수 있다.
  • 사실 실제 색상이 저장되는 순서는 RGB 순서가 아니라 BGR 순서이다.
    • 이 말을 이해하기까지 오랜시간이 걸렸다. 이건 3차원의 이미지 형식을 1차원 배열로 표현하기 때문인데, 나중에 LUT에 관한 글에서 자세히 설명하는 걸로...

2. 그렇다면 iOS 환경에서 픽셀의 RGB 값을 가져오는 방법은?

간단하다. UIImageCGImage로 변환하면 된다.

UIImage

앱상에서 이미지 데이터를 관리하는 객체, UIKit안에 포함되어 있다.

  • 이미지에 대한 정보를 담고 있는 UIImage를 UIImageView에 넣으면, UIImageView가 그 정보를 읽고 사용자에게 보여준다.
  • 가장 상위에 있는 존재, UIImage의 immutable 특성과 관련 있음. 불변하는 객체임. 그래서 UIImageView를 업데이트 할 때도 새로운 UIImage를 만들어서 업데이트 해야함
  • 따라서 뭔가 이미지를 변형하고 싶을 때는 UIImage를 CGImage, CIImage로 변환해야 한다. 반대로 처리가 완료된 CGImage, CIImage가 제공하는 데이터를 UIImage가 받아와 이미지 객체로 만들어낼 수 있다.

CGImage (Core Graphics)

비트맵 이미지 또는 이미지 마스크 Core Graphics 안에 포함되어 있다.

Core Graphics의 공식문서를 보면, 'Handle path-based drawing, antialiased rendering, gradients, images, color management, PDF documents, and more.' 라고 최상단에 설명되어 있다. 즉, 이미지의 색상, 그라디언트, 음영, 렌더링 등 LUT와 관련된 작업을 하려면 이 프레임워크를 반드시 사용해야하는 것이다. iOS2.0 이상부터 지원한다.

  • CGImage의 설명은 심플하다. A bitmap image or image mask. 즉, 이미지의 비트데이터인 것.
  • CGContext 안에서 비트맵 작업, 처리를 진행할 수 있고, 그 결과물을 UIGraphicsGetCurrentContext() 을 이용해 CGImage로 가져올 수 있다. 이렇게 작업이 완료된 이미지는 UIImage(cgImage: cgimg) 이런 식으로 다시 UIImage로 바꾸어 UI에 보여준다.

정리

  • UIImage, Image(SwiftUI) : 이미지를 랜더링해서 유저에게 보여주기 위해 사용됨. 이미지 자체는 불변함.
  • CGImage : 이미지에 비트맵 처리를 가할 때 CGContext와 CGImage를 사용함. CPU만 사용해 계산이 느린 경우가 있음.

즉, LUT와 원본 이미지를 CGImage(비트맵)으로 변환하고, 두 비트맵 배열을 인자로 받아 각 RGB 값을 변환해주는 함수를 만들면 되는 것이다.

필터앱을 만들기 위한 아이디어가 어느정도 구상되었다.

profile
삽질의 기록들 👨‍💻

0개의 댓글