画像加工
フィルター
swift4
Xcode9

【iOS】画像にフィルター(Apple標準)をかける

※ この記事はエキサイトAdvent Calendar 2017 10日目の記事です。

エキサイトブログのiOSを担当しています
エキサイトのブログアプリver4のリリースで以下の3つの機能をリリースしました。
(Gif画像, 画像加工, カメラ)
今回は画像加工について解説していきますー

ダウンロードよろしくお願いしまーす!!
エキサイトブログ

画像加工

今回は、二種のフィルターを使っておでんの画像を加工して、
おでんの画像に温かみを吹き込みたいと思います。
二種類のフィルターに関しては、Appleが提供しているフィルターを使用します。公式

二種類のフィルター

CIVibrance

画像の自然な彩度を調整できるフィルターです。
inputAmountというパラメータを調整することで画像の彩度を調整できます

CIPhotoEffectTransfer

あらかじめパラメータが設定されたフィルターです。
ビンテージ写真のフィルムを模した風にフィルターをかけることができます。
自分でパラメータをいじることはできません。

実装

おでんの画像を加工して暖かくしていきます。
以下の用にストーリーボードに配置していきます。
ウォームボタンを押すとCIPhotoEffectTransferAfterフィルターをAfter画像にかける。
スライダーを調整するとCIVibranceフィルターをAfter画像にかける。

ViewController.swift
// 鍋写真のAfterの写真を表示するため
@IBOutlet weak var nabeAfterImageView: UIImageView!
// 自然な彩度を調整するスライダー
@IBOutlet weak var saidoSlider: UISlider!
// ウォームボタン
@IBOutlet weak var warmButton: UIButton!

スクリーンショット 2017-12-09 22.25.15.png

・UILabel x3
・UIImageView x2 (おでんの画像)
・UIButton x1 (ウォームボタン)
・UISlider x1 (自然な彩度スライダー)

フィルター

画像とフィルター名とパラメータを入力すると,フィルターがかかった画像が出力されるメソッドを作成する!

ViewController.swift
    func filter(image: UIImage, filterName: String, param: (Float, String)?) -> UIImage? {
        // UIImageをCIImageに変換し、フィルター名からフィルターを作成する
        guard let ciImage = CIImage(image: image),
            let filter = CIFilter(name: filterName) else {
                return nil
        }

        // パラメータがある場合は、フィルターにパラメータを加える
        filter.setDefaults()
        if let param = param {
            filter.setValue(param.0, forKey: param.1)
        }
        // 作成したフィルターにCIImageをぶち込んむ
        filter.setValue(ciImage, forKey: kCIInputImageKey)

        // 作成したフィルターからCIImageを取り出し、CIImageをCIContextでCGImageに変換する
        guard let outputCIImage = filter.outputImage,
            let cgImage = ciContext.createCGImage(outputCIImage, from: outputCIImage.extent) else {
                return nil
        }

        // CGImageを調理してUIImageを作成する
        return UIImage(cgImage: cgImage, scale: nabeScale, orientation: nabeOrientation)
    }

CIVibrance (スライダーのアクション)

ViewController.swift
@IBAction func adjustSaido(_ sender: UISlider) {
    nabeAfterImageView.image = filter(image: warmButton.isSelected ? filteredImage : nabeBeforeImage, filterName: "CIVibrance", param: (sender.value, "inputAmount"))
}

CIVibranceフィルターのinputAmountのパラメータは
最大値3,最小値0があるので、それをスライダーに設定する必要がある

ViewController.swift
// スライダーの設定
func setupSlider() {
    saidoSlider.value = 0
    saidoSlider.minimumValue = 0
    saidoSlider.maximumValue = 3
}

CIPhotoEffectTransfer(ボタンのアクション)

ViewController.swift
@IBAction func warmImage(_ sender: UIButton) {
    nabeAfterImageView.image = filter(image: nabeBeforeImage, filterName: "CIPhotoEffectTransfer", param: nil)

フィルター後

おでんが暖かくなりましたね
スクリーンショット 2017-12-09 22.56.19.png