LoginSignup
0
0

More than 1 year has passed since last update.

【iOS, Swift】CIFilterで点描してみた

Posted at

環境

  • Xcode:13.3.1
  • Swift:5.6

点描のソースコード例

点描するには、CIFilterの「CIPointillize」を使う

class SampleViewController: UIViewController {

    @IBOutlet weak var testDisplayImage: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // AssetsにDummyって名前の適当な画像を置く
        let dummyImage = UIImage(named: "Dummy")!
        let pointillizeImage = addPointillizeEffect(for: dummyImage)
        self.testDisplayImage.image = pointillizeImage
    }

    func addPointillizeEffect(for image: UIImage) -> UIImage {
        // どこらへんに描画するか(今回は中央に描画されるように設定)
        let center: CIVector = CIVector(x: self.testDisplayImage.bounds.midX, y: self.testDisplayImage.bounds.midY)
        // 丸の大きさ
        let radius = 40.0
        
        if let inputImage = image.toCIImage() {
            let filter: CIFilter = CIFilter(name: "CIPointillize",
                                            parameters: [kCIInputImageKey: inputImage,
                                                         kCIInputRadiusKey : radius,
                                                         kCIInputCenterKey : center])!
            // CIPointillizeになった画像が出力される
            if let outputImage = filter.outputImage {
                // CIContextを通してCGImageに変換
                let context = CIContext(options: nil)
                if let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
                    let filteredImage = UIImage(cgImage: cgImage)
                    return filteredImage
                }
            }
        }
        // 変換できなかったら元の画像を返す
        return image
    }
}

extension UIImage {
    
    func toCIImage() -> CIImage? {
        if let ciImage = self.ciImage {
            return ciImage
        }
        if let cgImage = self.cgImage {
            return CIImage(cgImage: cgImage)
        }
        return nil
    }
}

※ UIImageViewは、SafeAreaいっぱいになるような制約をつけてる

実行結果

  • 左:結果
  • 右:元々の画像

IMG_0102.PNG IMG_0101.PNG

補足

  • パラメータの設定

加工したい画像は、kCIInputImageKeyで指定する。必須。

どこらへんに描画するかは、kCIInputCenterKeyで指定する。
なにも設定しなければデフォルト値が設定される。

丸の大きさは、kCIInputRadiusKeyで指定する。
なにも設定しなければデフォルト値が設定される。画像サイズに対しての丸の大きさ。

CIFilter.setValue(Any?, forKey: String) でもパラメータを設定できる

  • リリース処理

古い記事だと、ContextとCGImageのリリース処理をしているが、Swift5でリリース処理を書くと、
'CGImageRelease' is unavailable: Core Foundation objects are automatically memory managed
というメッセージがでる。もうリリース処理はいらないのかも。

参考になった記事

  • Appleのリファレンス

  • UIImageのextensionについて
    • Assetsに置いてある画像からCIImageを取得しようとすると、CIImageがnilになってしまった。これを回避する方法を以下の記事を参考にした。

  • 実行結果からわかるとおり、もともとの画像より小さくなって出力されてしまう。
    • どうにかしたい時に参考になる。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0