개인적으로 이미지나 비디오 등의 미디어 플레이, 편집 등 멀티미디어 관련 기술에 관심이 많아 자료를 많이 찾아보는 편인데, 최근 미디어에 여러 필터를 적용하는 방법을 찾아보았습니다.
이번 시간에는 미디어에 다양한 효과를 주는 방법 중 Core Image
(이하 '코어 이미지') 프레임워크에서 지원하는 CIFilter
를 이용하여 사진에 다양한 효과를 주는 방법에 대해 알아보려고 합니다.
Core Image
코어 이미지는 Apple의 퍼스트파티 프레임워크의 하나로, 정지 영상 및 동영상 이미지에 고성능 처리를 제공하는 이미지 처리 및 분석 기술입니다.
코어 이미지를 사용해서 시스템에서 제공하거나 혹은 사용자가 지정한 다양한 필터를 사용하여 이미지를 처리하거나 필터를 연결하여 복잡한 효과를 만들 수 있습니다.
CIFilter
CIFilter
는 코어 이미지에서 하나 이상의 입력 이미지를 처리하거나 새로운 이미지 데이터를 생성하여 이미지를 제작하는 이미지 프로세서입니다.
이미지를 처리하거나 필터 제너레이터를 만들거나, 또는 사용자 정의 필터를 작성할 때 내장된 코어 이미지 필터를 활용하려면 CIFilter
객체를 CIImage
, CIContext
및 CIColor
와 같은 다른 코어 이미지 클래스와 함께 사용합니다.
CIImage
의 처리는 CIContext
객체에서 이루어집니다.CIContext
는 생성하는 데 많은 비용이 들기 때문에 초기 설정 중에 생성하여 필요할 때마다 앱 전체에서 재사용하는 것이 좋습니다.
let context = CIContext()
이렇게 만들어 둔 CIContext
는 후에 필터를 선택한 후에, 아래와 같이 원본 이미지에 필터를 적용하여 CGImage
로 내보내는 등의 용도로 사용됩니다.
let cgImage = context.createCGImage(image, from: image.extent)
KVC 방식으로 필터 적용하기
일반적으로 CIFilter
는 하나 이상의 이미지를 입력으로 받아 CIImage
를 생성합니다.
하지만, 일부 필터는 다른 유형의 입력 매개변수를 기반으로 이미지를 생성하기도 합니다.CIFilter
객체의 매개변수는 키-값(key-value)을 사용하여 설정 및 검색됩니다.
아래는 KVC(Key-Value Coding) 방식을 사용하여 SepiaTone 필터를 적용하는 함수의 예시입니다.
func sepiaFilter(_ image: CIImage, intensity: Double) -> CIImage? {
let filter = CIFIlter(name: "CISepiaTone")
filter?.setValue(image, forKey: kCIInputImageKey)
filter?.setValue(intensity, forKey: kCIInputIntensityKey)
return filter?.outputImage
}
이렇게 KVC 방식으로 필터를 적용할 수도 있지만, 이 경우 CIFilter의 name
을 문자열로 직접 작성하므로 오타가 발생할 수도 있고, 어떤 키와 어떤 값을 사용할 수 있는지를 알기가 비교적 어렵습니다.
type-safe API 사용하여 필터 적용하기
코어 이미지에서는 위와 같이 문자열 기반 API에 의존할 때 발생할 수 있는 런타임 오류를 방지하기 위해 type-safe CIFIlter 인스턴스를 생성하는 메서드를 제공합니다.
type-safe API를 사용하려면 CoreImage.CIFIlterBuiltins
를 import 해야 합니다.
import CoreImage
import CoreImage.CIFilterBuiltins
type-safe 접근 방식은 옵셔널이 아닌 필터를 반환합니다.
반환된 필터는 관련 프로토콜(예를 들어 sepiaTone()
은 CISepiaTone
)을 준수하므로 매개 변수를 프로퍼티로 사용할 수 있습니다.
아래의 코드는 위에서 KVC 방식을 사용하여 작성했던 SepiaTone 필터를 type-safe API를 사용하여 다시 작성한 함수 예시입니다.
func sepiaFilter(_ image: CIImage, intensity: Float) -> CIImage? {
let filter = CIFilter.sepiaTone()
filter.intensity = intensity
filter.inputImage = image
return filter?.outputImage
}
마무리
이번 시간에는 Core Image
의 CIFilter
를 사용하여 사진에 시스템 필터 효과를 주는 방법에 대해 알아 보았습니다.
CIFilter
는 위에서 설명한 sepiaTone
필터 뿐만 아니라 bokehBlur
, boxBlur
등의 Blur Filter, gammaAdjust
, toneCurve
등의 Color Adjustment Filter, colorInvert
, falseColor
등의 Color Effect Filter 등 다양한 종류의 필터를 사용할 수 있습니다.
더 다양한 필터는 아래의 필터 카테고리에서 각각의 카테고리 페이지를 참조하여 확인할 수 있습니다.
필터 카테고리
- Blur Filters
- Color Adjustment Filters
- Color Effect Filters
- Composite Operations
- Convolution Filters
- Generator Filters
- Geometry Adjustment Filters
- Gradient Filters
- Halftone Effect Filters
- Sharpening Filters
- Stylizing Filters
- Tile Effect Filters
- Transition Filters
위에서 사용된 코드 및 간단한 예시 코드는 여기에서 확인하실 수 있습니다.
후기
사실 동영상에 필터를 적용하는 방법을 먼저 공부하기 시작했는데, 영상에 필터를 적용하는 방법을 작성하기에 앞서 사진에 적용하는 방법을 먼저 작성하고 싶어서 이렇게 정리해봤는데요.
공부할 때는 다양한 시스템 필터를 이렇게 저렇게 사용해보느라 시간이 오래 걸렸는데, 막상 글로 옮기면서 불필요하거나 중복되는 내용들을 다 잘라내고 주요 내용만 남기다보니 생각했던 것보단 글이 많이 짧다는 느낌이 드네요.
또, 처음에 작성할 때는 이 필터 저 필터에 대해 다 정리하다보니 사진도 많았었는데, 불필요한 내용을 삭제하다보니 사진이 하나도 남지 않게 된 부분도 많이 아쉽네요.
이렇게 시스템에서 제공하는 필터 말고도 더 다양한 효과에 대해서도 공부하고 있는데, 빠른 시간 내에 그 내용에 대해서도 작성할 수 있으면 좋겠습니다.
참고자료
https://developer.apple.com/documentation/coreimage
https://developer.apple.com/documentation/coreimage/cicontext
https://developer.apple.com/documentation/coreimage/cifilter
'Swift > iOS' 카테고리의 다른 글
[iOS] String Catalog - Xcode 15 이후의 iOS 앱에서 다국어 지원하기 (feat. Localization) (0) | 2024.03.31 |
---|---|
[iOS] Stretchable Image (a.k.a iOS 9-Patch) (0) | 2024.01.21 |
[Cocoa Design Patterns] KVO 패턴 (0) | 2023.07.02 |
[iOS] 실제 디바이스가 없는 경우의 개발 환경 (0) | 2023.06.14 |
[Core NFC] Core NFC 훑어보기 (0) | 2023.06.04 |