Genta Hirauchi

公開日:2020/04/07
更新日:2020/08/03

【Swift CIFilter】CIPhotoEffectで画像に効果を加える方法を解説

  • 画像のトーンカーブを補正する方法が知りたい。

SwiftのCore Imageには、CIFilterという、画像の補正を行うことができるクラスがあります。

CIFilterには、さまざなま画像補正のフィルタが用意されております。本記事では、その中のCIPhotoEffectというフィルタを使用し、画像に効果を加える方法を解説致します。

目次

CIPhotoEffectについて

CIPhotoEffectは、画像に効果を加える際に使用されるCore Image Filterです。

CIPhotoEffectには、以下のフィルタが用意されております。

CIPhotoEffectChrome 誇張された色のビンテージ写真
CIPhotoEffectFade 色が薄くなったビンテージ写真
CIPhotoEffectInstant 歪んだ色のビンテージ写真
CIPhotoEffectMono 低コントラストの白黒写真
CIPhotoEffectNoir 誇張されたコントラストの白黒写真
CIPhotoEffectProcess クールな色を強調したビンテージ写真
CIPhotoEffectTonal コントラストを大幅に変更しない白黒写真
CIPhotoEffectTransfer 温かみのある色を強調したビンテージ写真

Reference: CIPhotoEffectChrome | Core Image Filter Reference

CIPhotoEffectで画像に効果を加える方法

では、CIPhotoEffectで、画像に効果を加える方法を解説致します。

以下は、ボタンをタップすると、タップした効果を画像に加えるサンプルコードです。

  • ViewController.swift
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var effectLabel: UILabel!
    @IBOutlet weak var collectionView: UICollectionView!

    private var ciFilter: CIFilter!
    private var ciImage: CIImage!

    private let effectList: [String] = [
        "CIPhotoEffectChrome",
        "CIPhotoEffectFade",
        "CIPhotoEffectInstant",
        "CIPhotoEffectMono",
        "CIPhotoEffectNoir",
        "CIPhotoEffectProcess",
        "CIPhotoEffectTonal",
        "CIPhotoEffectTransfer"
    ]

    public var toneCurveValueList: [Float] = [0.0, 0.25, 0.50, 0.75, 1.0]

    override func viewDidLoad() {
        super.viewDidLoad()

        title = "効果"

        guard let uiImage = UIImage(named: "sample"), let ciImg = uiImage.ciImage ?? CIImage(image: uiImage) else { return }
        ciImage = ciImg

        imageView.image = uiImage

        let layout = UICollectionViewFlowLayout()
        layout.itemSize = CGSize(width: 220, height: 50)
        collectionView.collectionViewLayout = layout
    }
}

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return effectList.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
        cell.backgroundColor = .gray
        if let label = cell.contentView.viewWithTag(1) as? UILabel {
            label.text = effectList[indexPath.row]
        }
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        effectLabel.text = effectList[indexPath.row]

        // 各効果のCIFilterの生成
        ciFilter = CIFilter(name: effectList[indexPath.row])

        // 入力画像の設定
        ciFilter.setValue(ciImage, forKey: kCIInputImageKey)

        // Filter適応後の画像を表示
        if let filteredImage = ciFilter.outputImage {
            imageView.image = UIImage(ciImage: filteredImage)
        }
    }
}

CIFilter(name: フィルタ名)で、各効果フィルタのインスタンスを生成しております。

その後、生成したCIFilterのインスタンスに対し、setValue(ciImage, forKey: kCIInputImageKey)で、入力画像の設定を行っております。

そして、outputImageで、効果が加えられたCIImageを取得し、UIImageに変換後、画面に表示しております。

Point
  • CIFilter(name: フィルタ名)で、フィルタを生成する
  • setValue(CIImage, forKey: kCIInputImageKey)で、入力画像を設定する
  • outputImageで、補正されたCIImageを取得する

まとめ

  • CIFilter(name: フィルタ名)で、フィルタを生成する
  • setValue(CIImage, forKey: kCIInputImageKey)で、入力画像を設定する
  • outputImageで、補正されたCIImageを取得する