CoreImage는 Apple의 실시간 이미지 및 비디오 처리 프레임워크로, 색상 보정, 블러, 텍스처 오버레이 및 감지를 위한 수십 개의 내장 CIFilter를 제공합니다. Apple 문서에 따르면, CoreImage는 iOS 기기에서 고성능 픽셀 처리를 위해 GPU를 사용합니다. 이 프레임워크는 불변의 이미지 객체로서의 CIImage와 품질 손실 없이 효과를 구성하는 필터 체인을 지원합니다.
핵심 요점
CoreImage는 macOS 10.4 Tiger에서 처음 도입되고 iOS 5.0으로 포트된, Apple의 래스터 이미지 및 비디오 처리 프레임워크입니다. Core Graphics나 UIKit과 달리, CoreImage는 픽셀 셔더 레벨에서 작동하며, 병렬 계산을 위해 GPU를 사용합니다. 이를 통해 볼로책, 색상 보정, 모핑과 같은 복잡한 효과를 메가픽셀 해상도 이미지에 밀리초 단위로 적용할 수 있습니다.
CoreImage 아키텍처는 늘어진 평가(lazy evaluation) 개념에 기초하여 건설되었습니다. CIFilter는 CIContext에서 렌더링될 때까지 처리를 수행하지 않습니다. 개발자는 여러 CIFilter의 체인을 구축하여 한 필터의 출력을 다른 필터의 입력에 연결하며, render 호출만이 완전한 GPU 파이프라인을 시작합니다. 이는 그래픽스 카드를 통한 패스 수를 최소화하고 성능을 유지합니다.
CoreImage는 넓은 색상 영역(P3, sRGB, 선형 sRGB), HDR 이미지 및 16비트와 32비트 픽셀 포맷 작업을 지원합니다. Neural Engine이 탑재된 기기에서 CoreImage는 GPU 셔더와 Core ML을 결합하여 지능적 처리를 수행할 수 있습니다. 예를 들어 iOS 17의 사진 앱에 구현된 머신 러닝 기반 자동 색상 보정과 같습니다.
세 가지 주요 클래스가 CoreImage의 코어를 구성합니다: CIImage(데이터), CIFilter(작업), CIContext(실행 환경). 각 클래스는 파이프라인의 고유 단계를 담당하며 책임을 혼합하지 않습니다.
CIImage는 이미지를 설명하지만 픽셀 데이터를 직접 포함하지 않는 가벼운 객체입니다. UIImage, CGImage, Metal 텍스처, GL 텍스처 또는 디스크의 파일로부터 생성할 수 있습니다. CIImage는 불변이믰로, 필터 적용은 원본을 변경하지 않고 새로운 CIImage를 생성합니다. 이를 통해 단계 간에 데이터를 복사하지 않고 변환 체인을 구축할 수 있습니다.
중요한 특징: CIImage는 렌더링 전까지 화면 해상도나 색상 공간에 제한되지 않습니다. 동일한 CIImage를 화면용 UIImage와 다른 매개변수로 인쇄용 TIFF 파일로 렌더링할 수 있으며, CoreImage는 자동으로 처리를 대상 컨텍스트에 맞게 적응시킵니다.
CIFilter는 효과를 적용하기 위한 주요 클래스입니다. 각 CIFilter는 입력 매개변수( inputImage, inputIntensity, inputRadius 등)와 하나의 출력 이미지를 가진 셔더 프로그램입니다. Apple은 200개 이상의 내장 CIFilter를 제공하며, 카테고리별로 그룹화되어 있습니다: CICategoryColorEffect(색상 보정), CICategoryBlur(블러), CICategoryStylize(스타일리이션), CICategoryGeometryAdjust(기하학적 변환).
커스텀 CIFilter를 만들려면, 개발자는 Metal 셔더(CIKernel)를 작성합니다. 각 픽셀을 독립적으로 처리하는 Metal Shading Language의 프래그먼트 셔더입니다. 컴파일 후, 셔더는 CIFilter 서브클래스로 등록되며 Apple의 내장 필터와 함께 체인에서 사용할 수 있습니다.
| 카테고리 | 필터 예 | 목적 |
|---|---|---|
| ColorEffect | CIColorControls | 밝기, 대비, 포화도 |
| Blur | CIGaussianBlur | 조절 가능한 반지름의 가우시안 블러 |
| Stylize | CIPixellate | 지정된 스케일로 픽셀화 |
| GeometryAdjust | CIAffineTransform | 어핀 행렬을 통한 회전, 확대/축소, 이동 |
| Composite | CISourceOverCompositing | 알파 채널로 이미지 합성 |
CIContext는 GPU 리소스 할당, 셔더 컴파일 및 버퍼링을 관리하는 무거운 객체입니다. CIContext를 만드는 것은 비용이 크기 때문에 Apple은 애플리케이션 생명 주기에 한 번 만들고 재사용할 것을 권장합니다. 컨텍스트는 특정 GPU(Metal, OpenGL) 또는 CPU에 바인되며 출력 이미지의 색상 공간을 결정합니다.
CIFilter 라이브러리는 지속적으로 확장되고 있습니다. iOS 17은 HDR 처리와 머신 러닝을 위한 새로운 필터를 추가했습니다. 모든 내장 필터는 Apple Developer Documentation에 문서화되어 있으며, 카테고리나 이름으로 검색할 수 있습니다. 기기에서 사용 가능한 필터를 확인하려면 CIFilter.filterNames(inCategory:)를 사용하세요.
CoreImage의 주요 기능은 여러 CIFilter를 하나의 체인으로 구성하는 것입니다. 한 필터의 출력은 inputImage 매개변수를 통해 다른 필터의 입력으로 제공됩니다. CoreImage는 렌더링 단계에서 체인을 최적화하여 동일한 색상 공간에서 작동하는 인접 필터를 단일 GPU 패스(커널 퓨전)로 결합합니다. 이를 통해 개발자의 개입 없이 성능이 향상됩니다.
커스텀 효과를 만들려면, 개발자는 [[kernel]] 어노테이션이 있는 Metal 함수를 작성합니다. 함수는 픽셀 좌표를 수신하고 색상을 반환합니다. CoreImage는 셔더를 GPU에 전달하며, 이미지의 모든 픽셀에 대해 병렬로 실행됩니다. 커스텀 필터는 비선형 곡선 세피아, 분산 블러, 필름 그레인 시뮬레션같은 고유한 시각적 효과에 다양하게 사용됩니다.
#include <CoreImage/CoreImage.h>
[[kernel]] float4 customFilter(sample_t s, float intensity) {
float4 result;
result.rgb = s.rgb * (1.0 - intensity) + s.r * intensity;
result.a = s.a;
return result;
}
CoreImage는 중간 결과물의 캐시를 자동으로 관리합니다. 동일한 필터 체인이 다른 이미지에 적용되는 경우, CoreImage는 컴파일된 셔더를 재사용할 수 있습니다. 최대 성능을 위해 프레임마다 CIContext를 만드는 것을 피하고 하나의 컨텍스트를 사용하며 필터의 입력 매개변수를 재설정하세요.
CIDetector는 Vision이나 Core ML을 사용하지 않고 이미지에서 의미적 객체를 감지하기 위한 CoreImage 하위 시스템입니다. CIDetector는 네 가지 유형의 감지를 지원합니다: 얼굴(CIDetectorTypeFace), 텍스트(CIDetectorTypeText), QR 코드(CIDetectorTypeQRCode), 사각형(CIDetectorTypeRectangle). 감지기는 NEON 명령어에 대한 최적화를 통해 CPU에서 동작하며, 강력한 GPU가 없는 기기에서도 안정적인 속도를 보장합니다.
얼굴 감지기 CIDetectorTypeFace는 얼굴 경계 좌표, 눈과 입 위치가 포함된 CIFaceFeature 배열을 반환합니다. iOS 12 이후, CIDetector는 미소(hasSmile)와 왼/오른쪽 눈의 위치(leftEyeClosed, rightEyeClosed)도 감지합니다. 감지 정확도는 대부분의 AR 및 사진 애플리케이션에 충분하지만, 중요한 시나리오에서는 Apple이 Vision.framework을 권장합니다.
CIDetectorTypeRectangle은 이미지에서 문서, 명함, 기기 화면과 같은 사각형 영역을 찾습니다. 감지기는 사각형 구라부를 구성하는 네 개의 점이 있는 CIRectangleFeature를 반환합니다. WWDC 2024에 따르면, 사각형 감지기는 Vision과 동일한 신경망 아키텍처를 사용하지만, 메모리 소비가 더 적습니다. 이로 인해 문서 스캐너 애플리케이션과 같은 실시간 프레임 스트림 처리에 적합합니다.
실제 예시가 CoreImage에 대한 이해를 더욱 공곡할 것입니다. 사진에 색상 필터 적용하기와 경계 상자를 그리는 얼굴 감지라는 두 가지 일반적인 시나리오를 살펴보겠습니다.
CISepiaTone 필터의 기본 예제로, 컬러 이미지를 세피아 톤으로 변환합니다. 필터는 inputIntensity 매개변수를 0(원본)부터 1(최대 효과)까지 수용합니다. 늘어진 평가를 참고하세요. filter.outputImage가 반환하는 CIImage는 픽셀을 포함하지 않으며, context.createCGImage가 호출될 때만 렌더링이 일어난니다.
import CoreImage
guard let inputImage = CIImage(image: uiImage) else { return }
let filter = CIFilter(name: "CISepiaTone")
filter?.setValue(inputImage, forKey: kCIInputImageKey)
filter?.setValue(0.8, forKey: kCIInputIntensityKey)
let context = CIContext()
let outputImage = filter?.outputImage
let cgImage = context.createCGImage(outputImage!, from: inputImage.extent)
let resultImage = UIImage(cgImage: cgImage!)
다음 예제는 CIDetector를 사용하여 이미지에서 얼굴을 찾고 각 감지된 얼굴 주변에 사각형을 그립니다. CIFaceFeature에는 이미지 좌표계(원점이 앜쪽 하단)의 좌표가 포함되어 있으므로, UIKit에서 그릴 때는 어핀 변환을 통한 좌표 변환이 필요합니다.
let detector = CIDetector(
ofType: CIDetectorTypeFace,
context: context,
options: [CIDetectorAccuracy: CIDetectorAccuracyHigh]
)
let features = detector?.features(in: inputImage) as? [CIFaceFeature]
for face in features ?? [] {
print("Face bounds: \(face.bounds)")
if face.hasSmile {
print("그 사람이 미소짓고 있습니다")
}
}
마지막 예제는 세 가지 필터의 체인을 보여줍니다: 색상 보정, 비네팅, 텍스처 오버레이. 처음 필터의 outputImage가 중간 렌더링 없이 둘째 필터에 inputImage로 전달되는 것을 참고하세요. createCGImage가 호출되면 CoreImage는 세 작업 모두를 하나의 GPU 패스로 결합합니다.
let colorFilter = CIFilter(name: "CIColorControls")
colorFilter?.setValue(inputImage, forKey: kCIInputImageKey)
colorFilter?.setValues([
kCIInputBrightnessKey: 0.1,
kCIInputContrastKey: 1.2
])
let vignetteFilter = CIFilter(name: "CIVignette")
vignetteFilter?.setValue(colorFilter?.outputImage, forKey: kCIInputImageKey)
vignetteFilter?.setValue(2.0, forKey: "inputRadius")
let finalImage = vignetteFilter?.outputImage
let result = context.createCGImage(finalImage!, from: inputImage.extent)
자주 묻는 질문
CoreImage는 GPU에서 동작하며 픽셀 작업(필터, 색상 보정)에 최적화되어 있지만, Core Graphics는 벡터 그리기와 2D 컨텍스트를 위한 CPU 라이브러리입니다. CoreImage는 일괄 이미지 처리에서 더 빠르고, Core Graphics는 단계적인 인터페이스 그리기에서 더 정확합니다.
네 — CoreImage는 AVPlayerItemVideoOutput 또는 AVCaptureOutput을 통한 개별 비디오 프레임 처리를 지원합니다. 스트리밍 처리를 위해서는 CIFilter와 함께 AVVideoComposition을 사용하며, CPU와 GPU 간에 프레임을 복사하지 않고 효과를 적용할 수 있습니다.
CoreImage는 기본적으로 sRGB 작업 색상 공간(kCGColorSpaceSRGB)에서 동작합니다. CIContext를 만들 때 HDR을 위한 확장 선형 sRGB나 넓은 색상 영역 디스플레이를 위한 Display P3와 같은 대체 공간을 지정할 수 있습니다.
체인의 필터 수에 제한은 없지만, 5–7개의 연속 필터마다 추가 GPU 패스가 생성됩니다. 10개 이상의 필터에는 체인을 그룹으로 나누고 중간 결과물을 렌더링하여 셔더 레지스터 제한을 넘지 않도록 하는 것이 좋습니다.
네 — CIDetector는 iOS 5.0 이상의 모든 기기에서 NEON 명령어를 사용하여 CPU에서 동작합니다. 감지 정확도는 모든 기기에서 동일하지만, Apple A12+ 칩에서는 하드웨어 가속 신경망으로 인해 속도가 더 빠릅니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.