티스토리 뷰

공부

Metal ) Custom Core Image Filter

Zedd0202 2020. 6. 16. 16:40
반응형

 

안녕하세요 :) Zedd입니다.

저번시간에 zeddios.tistory.com/1044

 

Metal ) Metal Tutorial 따라해보기 / Metal에서 중요한 개념 익히기

안녕하세요 :) Zedd입니다. Metal을 공부해야 할 일이 생겨서..기본적인 용어들(?)을 공부해보려고 합니다. 오늘 공부는 www.raywenderlich.com/7475-metal-tutorial-getting-started#toc-anchor-011 Metal Tutori..

zeddios.tistory.com

중요한 개념들을.....나름대로...알아보았는데요...

제가 지금 궁극적으로 해야 할 일은

custom core image filter를 만들어서 이미지에 적용하는 것입니다!!!!!!!!!!!!!!!!!!

 

그럼 이런 궁금증이 들죠.

저번에 zeddios.tistory.com/1019

 

iOS ) CIFilter 사용해보기

안녕하세요 :) Zedd입니다. 지금 어떤걸 하고 있는데..CIFilter를 사용해야해서요! CIFilter를 사용해보는 방법을 공부해보려고 합니다아ㅏ 그냥 간단하게만 볼거에용 먼저 CI를 보면 짐작하실 수 있듯

zeddios.tistory.com

CIFilter사용해보기라는 글을 썼었는데, 이건 뭔디

이건 이미 built-in된 core image filter를 이미지에 먹인거고,

제가 하고싶은건 custom core image filter를 내가 직접 만들어서 이미지에 먹이고 싶은거에요.

 

 

그럼 시작해봅시다. 

CIFilter글에서도 언급했듯이

developer.apple.com/library/archive/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html#//apple_ref/doc/uid/TP40004346

 

Core Image Filter Reference

Core Image Filter Reference

developer.apple.com

기본적으로 제공되는 필터들이 굉장히 많아요.

근데 내가 뭐 내가 ㅁ ㅓ...내가...

뭔 되도않는....필터를 만들고싶다고 생각해봅시다.

그럼 어떻게 하냐!?

 

iOS11+ 부터 Metal Shading Language (MSL)을 이용해서 

Custom Core Image Filter를 만들 수 있게 됐다고해요!!

 

요 MSL이 우리가 저번 시간에 본..!!!

이것입니당

 

+ ) 그럼 iOS 11이전에는 custom core image filter를 만드는게 안됐었냐?

MSL을 사용해서는 안됐었지만 Core Image Kernel Language를 사용해서는 됐었어요.

이 부분은 밑에 자세히 나옵니다. 

 

그럼 이 MSL로 뭔가를 작성하는게 가장 중요한 일이 되겠군요..

우리 zeddios.tistory.com/1019

 

iOS ) CIFilter 사용해보기

안녕하세요 :) Zedd입니다. 지금 어떤걸 하고 있는데..CIFilter를 사용해야해서요! CIFilter를 사용해보는 방법을 공부해보려고 합니다아ㅏ 그냥 간단하게만 볼거에용 먼저 CI를 보면 짐작하실 수 있듯

zeddios.tistory.com

CIFilter를 적용해봤잖아요?

그럼 내가 custom filter를 어딘가에 만들었다고 생각해봅시다. 

sepiaFilter를 이런식으로 가져왔었죠?

그러니까 제가 하고싶은 말은, 우리가 만든 Custom Filter 역시 CIFilter로 가져와야 하는 것입니다.

(꼭 그렇게 해야한다!!! 기 보다는 그럴 수 있다는 거에요.

CIFilter로 안만들고 CIImage를 extension하여 만들 수 도 있고..방법은 여러가지 입니다 :D)

즉, 제 필터는 CIFilter를 상속받아야한다는 것이죠.

CIFilter의 문서에 가보면,

https://developer.apple.com/documentation/coreimage/cifilter

이렇게 적혀있습니다.

 

너가 custom filter를 만들고 싶으면 CIFilter subclass할 수 있음ㅎ

- 둘 이상의 built-in Core Image Filter를 chain(연결)하고싶거나

- 너가 작성한 image-processing kernel을 사용하거나...

 

일단 제가 하고싶은건 built-in된 Filter들을 섞어서(?) 듣도보도 못한 이상한 Filter를 만들 수는 있겠죠!!! 하지만

아아- 난...나.만.의.."Filter"를 만들고싶다..

그러면 CIKernel을 사용해야합니다.

 

CIKernel

뭐 커널...? OS에서 배우던 그 커널..

CIKernel은 "Custom Core Image Filter를 만드는데 사용되는 GPU기반 이미지 처리 루틴"이라고 문서에서 말하네요.

Built-in 필터이든,,.,.우리가 만든것이든 상관없이 모든 필터의 핵심은 하나 이상의 kernel이에요.

제가

이렇게 built-in filter를 사용해도 내부적으로는 다 kernel을 사용하고 있습니다.

 

kernel language routine은 다음과 같은 특징이 있다고 하는데요,

리턴타입은

vec4(Core Image Kernel Language) 

or

float4(Metal Shading Language) 

이라고 합니다.

 

아..그럼 아까 MSL이야기 나왔으니까 나는 float4로 쓰면 되는건가..? 그럼 vec4는 언제쓰지...

https://developer.apple.com/documentation/coreimage/writing_custom_kernels

이런....로직으로 어떤 Language를 선택할건지 정하면 되는 것 같아요.

 

둘이 어떻게 다르냐면

https://developer.apple.com/documentation/coreimage/cikernel

이게 MSL,

https://developer.apple.com/documentation/coreimage/cikernel

 이게 Core Image Kernel Language입니다.

이 둘을 결정하는..가장 큰 것은 아마도

Device has Metal? 인데요.

위에서도 언급했듯이 iOS11+ 부터 Metal Shading Language (MSL)을 이용해서 

Custom Core Image Filter를 만들 수 있게 됐다고 했잖아요?

Metal은 "supported by macOS High Sierra, iOS 11 and tvOS 11"

그러니까 iOS11 미만 버전은 Metal을 가지고 있지 않다고 보시면 됩니다.

그럴리 없겠지만...😱..내가 iOS11 미만이라면..

그냥 선택의 여지가 없이.. Core Image Kernel Language를 사용해야하는거죠!

 

저는 MSL을 사용해볼게요!

 

 

CIKernel이야기 하다가 여기까지 온 것 같은데...암튼 CIKernel의 문서에 가보시면

이렇게 어쩌구 kernel들이 있는 걸 볼 수 있습니다. 얘네는 뭐고 그냥 CIKernel이 뭐냐..

 

custom filter가 color와 geometry정보를 동시에 처리하지 않아도 되는 경우에는, 

이미지 처리 코드를 분리해서 성능을 향상시킬 수 있대요!

color 처리 단계에서 CIColorKernel객체를 사용하고

geometry 처리 단계에서 CIWarpKernel객체를 사용하라고 합니다.

(CIBlendKernel은 두 이미지를 섞는다고 보면됨)

 

아무튼 각 어쩌고 Kernel을 "잘" 사용하면 성능이 올라간다는건데, 저는 그냥 CIKernel을 사용해볼게요.

 

자 그럼 우리가 해야 할 일을 정리해봅시다.

1. MSL로 Custom filter코드를 작성.

2. CIFilter 서브클래싱.

3. CIFilter 서브클래스 안에서 MSL로 작성한 코드를 불러와서...이미지에 적용한다.

 

뭐 이런식이 되겠네요. 해봅시다.

그럼 custom filter를 만들어야하는데, 저는 일단 MSL의 문법,....도 모르는 상태..ㅋ

developer.apple.com/metal/MetalCIKLReference6.pdf

애플이 웬일로...이런...레퍼런스를 줬네요.

아무튼 저는....ㅋ......그냥.......줍줍 하겠읍니다...ㅋ..

출처 : tech.unifa-e.com/entry/2019/05/17/185120

 

이름에서 예상하실 수 있다시피..gray화 해주는 친구입니다.

아니 이럴거면 custom filter왜 만드나? 라고 생각할 수 있지만 걍 봐주세요.

저 코드는 저번시간에 shader만들었던것처럼

Metal을 선택해주시고..파일이름은 아무거나여도 됩니다. 파일이름으로 찾는게 아니라 함수 이름으로 찾기때매 ㅎ

 

자 그럼 1번이 끝났으니 이제

2. CIFilter 서브클래싱 

자 이렇게 해주었습니다. 

저 default는 왜ㅔ 해주는지는 모르겠지만 CIKernel만드는데 필요함.

아무튼 중요한건 applyFilter인데요, kernel에 대충 apply때려버림

솔직히 저는 이 코드의 원리..라고 해야할까요..이걸 분석할 자신이 없습니다..

 

3. CIFilter 서브클래스 안에서 MSL로 작성한 코드를 불러와서...이미지에 적용한다.

방금 만든 ZeddFilter 인스턴스를 만들어서 grayscale filter가 적용된 CIImage를 가져오고, 다시 UIImage로 만들어서 뿌려줍니다. 

자 그럼 빌드해보면

grayscale함수 없는디?;;;하면서 에러가 납니다. crash는 우리가 try!로 해놔서 ㅎ

암튼 근데 우리

있는데 왜 오류 ㅡㅡ

developer.apple.com/metal/MetalCIKLReference6.pdf

를 열어보면,

Xcode Intergration부분이 있습니다. 

해야하는 작업은 2가지 인데요,

1. Build Setting에 가셔서 Metal을 검색하면

위와 같은 화면이 뜰텐데요, 그중 Other Metal Compiler Flags가 있을겁니다. 이걸

-fcikernel로 설정해야합니다. 

엥 나는 저 Metal Compiler - Build Options이 안뜨는데;;? 

-> 원래 없는게 맞고, metal파일이 프로젝트내에 있어야 저게 보입니다. 

 

2. User-Defined Setting추가.

Add User-Defined Setting을 눌러주고

MTLLINKER_FLAGS에 -cikernel을 지정해주세요.

이렇게요.

다시 빌드해보면

대충 이런 식으로 필터가 먹여지게 됩니다. 저는 UIImagePickerController를 사용해서 이미지 불러온거에요.

암튼...Kernel을 사용해서 필터를 먹이는 작업을 해봤습니다!....

뭔가 Kernel을 사용해봤다고 하니까.,,ㅋ 간지가 나기도 하고,,,ㅋ,,,,,ㅎ

ㅈㅅ

틀린 설명 있을 수 있음..

반응형