Home > Core Image Filters
Core Image Filters
Core Image์ GPU ๊ฐ์ ์ด๋ฏธ์ง ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ์ ํ์ตํฉ๋๋ค. 200๊ฐ ์ด์์ ๋ด์ฅ ํํฐ, ํํฐ ์ฒด์ด๋, ์ค์๊ฐ ์นด๋ฉ๋ผ ํํฐ ์ ์ฉ๊น์ง ๋ค๋ฃน๋๋ค.
๊ฐ์
Core Image๋ Apple์ GPU ๊ฐ์ ์ด๋ฏธ์ง ์ฒ๋ฆฌ ํ๋ ์์ํฌ์ ๋๋ค. ๋ธ๋ฌ, ์์ ์กฐ์ , ์๊ณก, ํฉ์ฑ ๋ฑ 200๊ฐ ์ด์์ ๋ด์ฅ ํํฐ(CIFilter)๋ฅผ ์ ๊ณตํ๋ฉฐ, ์ด๋ค์ ์ฒด์ธ์ผ๋ก ์ฐ๊ฒฐํ์ฌ ๋ณต์กํ ์ด๋ฏธ์ง ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
Core Image๋ ์ง์ฐ ํ๊ฐ(lazy evaluation) ๋ฐฉ์์ผ๋ก ๋์ํฉ๋๋ค. ํํฐ๋ฅผ ์ฐ๊ฒฐํด๋ ์ฆ์ ์ฒ๋ฆฌํ์ง ์๊ณ , ์ต์ข ๋ ๋๋ง ์ GPU์์ ํ ๋ฒ์ ์คํํ์ฌ ๋์ ์ฑ๋ฅ์ ๋ฌ์ฑํฉ๋๋ค.
์ธ์ ์ฌ์ฉํ๋์?
- ์ฌ์ง/์ด๋ฏธ์ง ํธ์ง ์ฑ (์์ ๋ณด์ , ํํฐ ํจ๊ณผ)
- ์ค์๊ฐ ์นด๋ฉ๋ผ ํํฐ (AVCaptureSession ์ฐ๋)
- ์ผ๊ตด ์ธ์ ๊ธฐ๋ฐ ์ดํํธ
- ์ด๋ฏธ์ง ํฉ์ฑ ๋ฐ ํ ์คํธ ์ค๋ฒ๋ ์ด
ํต์ฌ API
CIFilter & CIImage
CIImage๋ ๋ถ๋ณ(immutable) ์ด๋ฏธ์ง ๋ ์ํผ์ด๋ฉฐ, CIFilter๋ก ๋ณํํฉ๋๋ค. ํํฐ ์ฒด์ด๋์ ์ถ๋ ฅ CIImage๋ฅผ ๋ค์ ํํฐ์ ์
๋ ฅ์ผ๋ก ์ฐ๊ฒฐํ๋ฉด ๋ฉ๋๋ค.
// ์๋ณธ ์ด๋ฏธ์ง ๋ก๋
guard let inputImage = CIImage(image: uiImage) else { return }
// ๊ฐ์ฐ์์ ๋ธ๋ฌ ์ ์ฉ
let blur = CIFilter.gaussianBlur()
blur.inputImage = inputImage
blur.radius = 10.0
// ์์กฐ ์กฐ์ ์ฒด์ด๋
let hueAdjust = CIFilter.hueAdjust()
hueAdjust.inputImage = blur.outputImage
hueAdjust.angle = Float.pi / 4
// CIContext๋ก ์ต์ข
๋ ๋๋ง
let context = CIContext()
if let output = hueAdjust.outputImage,
let cgImage = context.createCGImage(output, from: output.extent) {
let result = UIImage(cgImage: cgImage)
}
CIContext ๊ด๋ฆฌ
CIContext๋ GPU ๋ฆฌ์์ค๋ฅผ ๊ด๋ฆฌํ๋ ๋ฌด๊ฑฐ์ด ๊ฐ์ฒด์
๋๋ค. ์ฑ ์๋ช
์ฃผ๊ธฐ ๋์ ํ๋๋ง ์์ฑํ์ฌ ์ฌ์ฌ์ฉํ๋ ๊ฒ์ด ํต์ฌ ์ฑ๋ฅ ์ ๋ต์
๋๋ค.
์นด๋ฉ๋ผ ํ์ดํ๋ผ์ธ
AVCaptureSession์์ ์ค์๊ฐ ํ๋ ์์ ๋ฐ์ Core Image ํํฐ๋ฅผ ์ ์ฉํ๋ฉด ๋ผ์ด๋ธ ์นด๋ฉ๋ผ ํํฐ๋ฅผ ๊ตฌํํ ์ ์์ต๋๋ค. AVCaptureVideoDataOutputSampleBufferDelegate์ ์ฝ๋ฐฑ์์ CMSampleBuffer -> CIImage ๋ณํ ํ ํํฐ๋ฅผ ์ ์ฉํฉ๋๋ค.
CIKernel
๋ด์ฅ ํํฐ๋ก ๋ถ์กฑํ ๋, Metal Shading Language๋ก ์ปค์คํ CIKernel์ ์์ฑํ์ฌ ๋๋ง์ ํํฐ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
๋ฐ๋ชจ ๋ชฉ๋ก
| # | ๋ฐ๋ชจ | ์ค๋ช |
|---|---|---|
| 1 | Filter Gallery | 15๊ฐ Core Image ํํฐ ์ธ๋ค์ผ ๊ทธ๋ฆฌ๋ + ๊ฐ๋ ์ฌ๋ผ์ด๋. Sepia, Chrome, Noir, Bloom, Crystallize ๋ฑ์ ํ๋์ ๋น๊ต. |
| 2 | Camera Filters | AVCaptureSession๊ณผ Core Image๋ฅผ ์ฐ๋ํ ์ค์๊ฐ ์นด๋ฉ๋ผ ํํฐ. ์๋ฎฌ๋ ์ดํฐ์์๋ ์ ์ฐจ์ ์ด๋ฏธ์ง ํด๋ฐฑ์ ์ฌ์ฉํฉ๋๋ค. |
| 3 | Filter Chain Builder | ์ต๋ 5๊ฐ ํํฐ ์ฌ๋กฏ์ ์คํ์ผ๋ก ์ฐ๊ฒฐํ์ฌ ์ปค์คํ ์ด๋ฏธ์ง ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ฑํฉ๋๋ค. |
| 4 | Custom Effects | ์ฌ๋ฌ ํํฐ๋ฅผ ์กฐํฉํ ์ฐฝ์์ ์ดํํธ(๊ธ๋ฆฌ์น, ๋นํฐ์ง, ํ์ํธ, ๋ค์จ ๊ธ๋ก์ฐ). Before/After ๋น๊ต ์ฌ๋ผ์ด๋ ํฌํจ. |
์ค์ ํ
Best Practices
CIContext๋ ์ฑ ์ ์ฒด์์ ํ๋๋ง ์์ฑํ์ฌ ์ฌ์ฌ์ฉํ์ธ์. ๋งค๋ฒ ์์ฑํ๋ฉด GPU ๋ฆฌ์์ค ๋ญ๋น๊ฐ ์ฌํฉ๋๋ค.- ํํฐ ์ฒด์ธ ์์๊ฐ ๊ฒฐ๊ณผ์ ํฐ ์ํฅ์ ์ค๋๋ค. ๋ธ๋ฌ -> ์์ ์กฐ์ ๊ณผ ์์ ์กฐ์ -> ๋ธ๋ฌ๋ ๊ฒฐ๊ณผ๊ฐ ๋ค๋ฆ ๋๋ค.
- ์ค์๊ฐ ์นด๋ฉ๋ผ ํํฐ์์๋
CIContext(options: [.useSoftwareRenderer: false])๋ก GPU ๋ ๋๋ง์ ๋ณด์ฅํ์ธ์. - Swift์ ํ์
์์ CIFilter API(
CIFilter.gaussianBlur())๋ฅผ ๋ฌธ์์ด ๊ธฐ๋ฐ API๋ณด๋ค ์ ํธํ์ธ์.
์ฃผ์ ์ฌํญ
- CIImage๋ ์ค์ ํฝ์
๋ฐ์ดํฐ๊ฐ ์๋ ๋ ์ํผ์
๋๋ค.
CIContext.createCGImage()๋ก ์ค์ ๋ ๋๋ง์ ํธ๋ฆฌ๊ฑฐํด์ผ ํฉ๋๋ค. - ํํฐ๋ฅผ ๊ณผ๋ํ๊ฒ ์ฒด์ด๋ํ๋ฉด GPU ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ๊ธ์ฆํ ์ ์์ต๋๋ค.
- ์นด๋ฉ๋ผ ํ๋ ์ ์ฒ๋ฆฌ ์, ์ด์ ํ๋ ์ ์ฒ๋ฆฌ๊ฐ ๋๋๊ธฐ ์ ์ ๋ค์ ํ๋ ์์ด ์ค๋ฉด ํ๋ ์์ ๋๋กญํด์ผ ํฉ๋๋ค.
- CIKernel ์์ฑ ์ Metal Shading Language ๋ฌธ๋ฒ๊ณผ Core Image์ ์ขํ๊ณ(์ ๊ทํ) ์ฐจ์ด์ ์ฃผ์ํ์ธ์.