はじめに
Swift で画像を扱うと、色々な型を使うことになります
- UIImage
- CGImage
- CIImage
通常、画像を画面に表示したいだけなら UIImage だけで問題ありません
画像処理をしようと思うと CGImage を使ってみることになり、
更に複雑さや高速さを求められるようになると CIImage を使うことになります
特にリアルタイム処理では CIImage を使わないと追いつきません
それぞれの違いについては以下の記事が参考になります
さて、では相互に変換するにはどうするか
以下の記事にまとめられていますが、情報が古いのと、場合によって結果が nil になることがあるため、補足します
実装環境
- macOS Big Sur 11.4
- XCode 12.5.1
- Swift 5.4.2
nil 回避方法
stack overflow にも出ていますが、 UIImage から CIImage を取り出そうとしたとき、 nil になることがあります
CIImage を元に作られた UIImage であれば問題ないのですが、そうではない(画像ファイルから読み込んだ場合など)は nil が返ります
というわけで、変換は以下のようにする必要があります
Extension にしておきました
UIImage -> CIImage
import UIKit
public extension UIImage {
func toCIImage() -> CIImage? {
if let ciImage = self.ciImage {
return ciImage
}
if let cgImage = self.cgImage {
return CIImage(cgImage: cgImage)
}
return nil
}
}
CIImage -> UIImage
import UIKit
extension CIImage {
func toCGImage() -> CGImage? {
let context = { CIContext(options: nil) }()
return context.createCGImage(self, from: self.extent)
}
func toUIImage(orientation: UIImage.Orientation) -> UIImage? {
guard let cgImage = self.toCGImage() else { return nil }
return UIImage(cgImage: cgImage, scale: 1.0, orientation: orientation)
}
}
CIImage は画像の向き、という概念を持っていませんが、 UIImage は向きの概念があるため、引数にしています
色々やっていると、この画像の向きの概念がややこしくなってくるわけですが、、、