公開日:2020/04/06更新日:2020/08/03
【Swift CIFilter】CIToneCurveでトーンカーブを補正する方法を解説

- 画像のトーンカーブを補正する方法が知りたい。
SwiftのCore Imageには、CIFilterという、画像の補正を行うことができるクラスがあります。
CIFilterには、さまざなま画像補正のフィルタが用意されております。本記事では、その中のCIToneCurveというフィルタを使用し、画像のトーンカーブを補正する方法を解説致します。
目次
CIToneCurveについて
CIToneCurveは、トーンカーブを補正する際に使用されるCore Image Filterです。
CIToneCurveには、以下のパラメータがあります。
inputImage | 入力画像(補正をかける画像) |
---|---|
inputPoint0 | ポイント0のトーンカーブ値 デフォルト値: [0.0, 0.0]、最小値: [0, 0]、最大値: [1, 1] |
inputPoint1 | ポイント1のトーンカーブ値 デフォルト値: [0.25, 0.25]、最小値: [0, 0]、最大値: [1, 1] |
inputPoint2 | ポイント2のトーンカーブ値 デフォルト値: [0.5, 0.5]、最小値: [0, 0]、最大値: [1, 1] |
inputPoint3 | ポイント3のトーンカーブ値 デフォルト値: [0.75, 0.75]、最小値: [0, 0]、最大値: [1, 1] |
inputPoint4 | ポイント4のトーンカーブ値 デフォルト値: [1.0, 1.0]、最小値: [0, 0]、最大値: [1, 1] |
Reference: CIToneCurve | Core Image Filter Reference
CIToneCurveでトーンカーブを補正する方法
では、CIToneCurveで、トーンカーブを補正する方法を解説致します。
以下は、スライダーを動かすと、その値をトーンカーブ値として、画像の補正を行うサンプルコードです。
- ViewController.swift
import UIKit
class ViewController: UIViewController, ToneCurveDelegate {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var tableView: UITableView!
private var ciFilter: CIFilter!
private let toneCurveTitleList: [String] = [
"inputPoint0",
"inputPoint1",
"inputPoint2",
"inputPoint3",
"inputPoint4"
]
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 ciImage = uiImage.ciImage ?? CIImage(image: uiImage) else { return }
imageView.image = uiImage
// CIFilterの生成
ciFilter = CIFilter(name: "CIToneCurve")
// 入力画像の設定
ciFilter.setValue(ciImage, forKey: kCIInputImageKey)
}
func valueSliderChanged(tag: Int, value: Float) {
toneCurveValueList[tag] = value
// トーンカーブの設定
ciFilter.setValue(CIVector(x: 0.0, y: CGFloat(toneCurveValueList[0])), forKey: "inputPoint0")
ciFilter.setValue(CIVector(x: 0.25, y: CGFloat(toneCurveValueList[1])), forKey: "inputPoint1")
ciFilter.setValue(CIVector(x: 0.5, y: CGFloat(toneCurveValueList[2])), forKey: "inputPoint2")
ciFilter.setValue(CIVector(x: 0.75, y: CGFloat(toneCurveValueList[3])), forKey: "inputPoint3")
ciFilter.setValue(CIVector(x: 1.0, y: CGFloat(toneCurveValueList[4])), forKey: "inputPoint4")
// Filter適応後の画像を表示
if let filteredImage = ciFilter.outputImage {
imageView.image = UIImage(ciImage: filteredImage)
}
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return toneCurveTitleList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "ToneCurveTableViewCell") as? ToneCurveTableViewCell else {
return UITableViewCell()
}
cell.delegate = self
cell.valueSlider.tag = indexPath.row
cell.titleLabel.text = toneCurveTitleList[indexPath.row]
cell.valueSlider.value = toneCurveValueList[indexPath.row]
cell.valueLabel.text = String(round(cell.valueSlider.value * 100) / 100)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
}
protocol ToneCurveDelegate: class {
func valueSliderChanged(tag: Int, value: Float)
}
class ToneCurveTableViewCell: UITableViewCell {
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var valueSlider: UISlider!
@IBOutlet weak var valueLabel: UILabel!
public weak var delegate: ToneCurveDelegate?
override func awakeFromNib() {
super.awakeFromNib()
}
@IBAction func valueChanged(_ sender: UISlider) {
valueLabel.text = String(round(sender.value * 100) / 100)
delegate?.valueSliderChanged(tag: sender.tag, value: sender.value)
}
}
CIFilter(name: “CIToneCurve”)で、CIToneCurveフィルタのインスタンスを生成しております。
その後、生成したCIFilterのインスタンスに対し、setValue(ciImage, forKey: kCIInputImageKey)で、入力画像の設定を行っております。
スライダーの値が変更されたら、setValue(CIVector(x: デフォルト値, y: トーンカーブ値), forKey: キー)で、トーンカーブ値の設定を行います。
そして、outputImageで、トーンカーブが補正されたCIImageを取得し、UIImageに変換後、画面に表示しております。
Point
- CIFilter(name: “CIToneCurve”)で、フィルタを生成する
- setValue(CIImage, forKey: kCIInputImageKey)で、入力画像を設定する
- setValue(CIVector(x: デフォルト値, y: トーンカーブ値), forKey: キー)で、トーンカーブ値を設定する
- outputImageで、補正されたCIImageを取得する
まとめ
- CIFilter(name: “CIToneCurve”)で、フィルタを生成する
- setValue(CIImage, forKey: kCIInputImageKey)で、入力画像を設定する
- setValue(CIVector(x: デフォルト値, y: トーンカーブ値), forKey: キー)で、トーンカーブ値を設定する
- outputImageで、補正されたCIImageを取得する
関連記事