본문 바로가기
iOS Swift/Today I Learned

CIImage, CGImage, UIImage 변환 및 개념 정리

by 호두빵 2022. 12. 28.

코딩을 하다보면 자주 마주하게 되는 이미지는 아마도 UIImage와 CGImage인 것 같습니다. 일단 이미지를 넣은 다음에 Xcode 가라사대 삑 이거 이대로 넣으면 안 되고 cgImage로 바꿔줘야해 하면 .cgImage만 후다닥 추가하던 저는 이번에 조금 더 개념을 확실하게 알아볼 수 있었습니다. 다른 포스팅에도 적었던 Mantis 라이브러리를 쓰면서 생겨난 궁금증에서 비롯된 것이었는데요. 사진을 찍거나/앨범에서 가져오거나 둘 중 한 가지의 방법으로 사진을 처리하고자 할 때 이상하게도 후자는 잘 되는데 전자는 똑같은 코드로 진행이 되지 않는 것이였어요. 넣어준 것은 uiImage로 둘 다 동일했는데 말이예요. 그래서 원작자에게 질문을 던졌습니다. 저의 단순한 추측으로는 해상도가 달라서 그런가? 싶었거든요. 그래서 해당 깃허브에 찾아가서 직접 아래와 같이 질문을 남겼습니다.

 

만약 이미지의 해상도가 너무 낮으면 크롭 기능을 쓸 수 없나요? 라고요. 

 

https://github.com/guoyingtao/Mantis/issues/241

 

If the image resolution is too low, it can't be cropped? · Issue #241 · guoyingtao/Mantis

Hello! I love utilizing your library. It's super convenient and easy to use. The thing is, the images that I've collected from the iPhone gallery works fine but the instant image doesn'...

github.com

 

며칠간 답장을 서로 주고 받으며 알아낸 결과는 해상도가 문제가 아니라 이미지의 유형 그 자체였습니다. 라이브러리에서는 cgImage로 받아서 처리가 필요한데, 제가 실시간으로 즉석에서 촬영한 이미지를 처리하는 과정에서 cgImage가 생략되고 곧바로 ciImage에서 uiImage로 넘겨주어서 크롭 기능이 정상적으로 작동하지 않았던 것이였어요. ciImage -> cgImage -> uiImage로 순서대로 해보니까 잘 되더라구요..(머쓱) 어쨌든 이번 기회에 세 가지 개념을 더 알아봐야겠다는 생각이 들었습니다. 

 

일단 큰 범주에서 이미지의 편집이 가능한가?를 생각해보면 uiImage / ciImage, cgImage 이렇게 둘로 가를 수 있겠습니다. 따라서 이미지를 변형하고 싶다면 uiImage는 ciImage, cgImage로 만들어줘야하고, 반대로 UIImageView에 넣어줘야 하는 경우에는 uiImage로 변환이 필요하겠죠. 모든 개념을 다 외우려고 해도 그러기가 힘들기 때문에 큰 특징적인 부분들만 짚자면, cgImage는 이미지에 비트맵으로 관리가 가능하다는 점, ciImage는 엄밀히 따지면 이미지 그 자체는 아니고 데이터의 모음이라는 점이겠습니다. 

 

그렇다면 일반적으로 변환하는 과정은 어떻게 진행이 될까요? 

 func convert(ciImage:CIImage) -> UIImage {
    let context = CIContext.init(options: nil)
    let cgImage = context.createCGImage(ciImage, from: ciImage.extent)!
    let image = UIImage.init(cgImage: cgImage)
    
    return image
}

 

이런식으로 단계를 거쳐 ciImage -> cgImage -> uiImage로 만들수가 있습니다.