Core ImageでBlur画像を作成する(Ver.1 & 2) [CIFilter]
CoreImageにてBlur画像を作成する為の関数についてメモを残しときます。
1. ガウジアンFilter関数 Ver.1
以下は元画像(CIImage)からBlur画像を作成する関数です。
UIImageからCIImageのゲット方法は let imageCIImage = CIImage(CGImage: imageUIImage.CGImage!)
です。
/** ガウジアンFilterを適応する - parameter inputCIImage : 元CIICmage - parameter value : フィルターのかけ度合い - returns : ぼかし画像のサイズ */ func applyGaussianBlurFilter(inputCIImage: CIImage, value: Float) -> CIImage { //ガウシンアン(ぼかし)フィルターの適応 let filter = CIFilter(name: "CIGaussianBlur") filter?.setValue(inputCIImage, forKey: kCIInputImageKey) filter?.setValue((value), forKey: kCIInputRadiusKey) let outputCIImage = filter?.outputImage guard let _outputCIImage = outputCIImage else { fatalError("applyGaussianBlurFilter does not work.") } return _outputCIImage }
CIImageからUIImageへの復元は以下を参考にして下さい。
(変数が何を示しているかは関数名から想像お願いいたします...汗)
let rect = CGRect(origin: CGPointZero, size: imageUIImage.size) let context = CIContext(options: nil) let cgImage = context.createCGImage(outputCIImage, fromRect: rect) let blurImage = UIImage(CGImage: cgImage)
2. ガウジアンFilter関数 Ver.2
Ver.1 のままだとガウジアンFilter適応後の画像端が透明色のグラデーションがかかってしまう問題があります。
対策としてClampフィルターを前処理として適応します。
この辺の詳細については以下を参照の事。
▶︎ objective c - Correct crop of CIGaussianBlur - Stack Overflow
以下、関数です。
/** ガウジアンFilterを適応する - parameter inputCIImage : 元CIICmage - parameter value : フィルターのかけ度合い - returns : ぼかし画像のサイズ */ func applyGaussianBlurFilter(inputCIImage: CIImage, value: Float) -> CIImage { //inputCIImageを何も考えずにCIGaussianBlurをかけると画面端に透過色が混じる //その対策の為、CIAffineClampを使い画面外側に拡大した元画像を配置し現象の対策を行う //URL: http://stackoverflow.com/questions/12839729/correct-crop-of-cigaussianblur let affineClampFilter = CIFilter(name: "CIAffineClamp") let xform = CGAffineTransformMakeScale(1.0, 1.0) affineClampFilter?.setValue(inputCIImage, forKey: kCIInputImageKey) affineClampFilter?.setValue(NSValue(CGAffineTransform: xform), forKey: "inputTransform") let outputAfterCalmp = affineClampFilter?.outputImage //ガウシンアン(ぼかし)フィルターの適応 let filter = CIFilter(name: "CIGaussianBlur") filter?.setValue(outputAfterCalmp, forKey: kCIInputImageKey) filter?.setValue((value), forKey: kCIInputRadiusKey) let outputCIImage = filter?.outputImage guard let _outputCIImage = outputCIImage else { fatalError("applyGaussianBlurFilter does not work.") } return _outputCIImage }
CIImageからUIImageへの復元はrectの取得方法に変更があります。
let rect = inputCIImage.extent let context = CIContext(options: nil) let cgImage = context.createCGImage(outputCIImage, fromRect: rect) let blurImage = UIImage(CGImage: cgImage)
所感
Ver.1で発生した「画面端透明問題」で結構ハマってしましました。
情報提供頂いた @akio0911 さんには感謝です!