Swift Playgroundsで学ぶiOSプログラミング 第61回
Edge(輪郭)とEdge Work(輪郭加工)を使ってみる
2種類のフィルターをスイッチで切り替えるプログラム
2017年11月22日 17時00分更新
前回から、内蔵カメラで撮影した画像をCore Imageのフィルターを使って加工するプログラムに取り組んでいます。前回は、とりあえず、Comic Effectというスタイライズ系のフィルターを使って、撮影した写真をマンガ風の絵にしてみました。
実は、そのフィルターは入力画像以外にパラメータを必要としないものでした。つまり、調整できる部分がないので、撮影した画像にそのままフィルターを適用することしかできなかったのです。
今回は、前回と同じスタイライズ系の2種類のフィルター、Edge(輪郭)とEdge Work(輪郭加工)を、スイッチで切り替えて適用できるようにしてみます。いずれのフィルターも、入力画像以外のパラメータを1つずつ取るので、その値をスライダーで設定できるようにもしましょう。ただし、2つのフィルターのパラメータの意味は異なり、設定として適切な数値の範囲も大きく違っています。それを1本のスライダーでどうやって設定するかということも1つの課題となります。
今回は名前の似た2つのフィルターを選びましたが、得られる効果はかなり印象の異なったものとなります。もちろん、それだけで満足していてはいけません。前回も述べたようにCore Imageには、数十種類以上のフィルターが揃っています。今回までに見るものとは、目的も機能も、そしてもちろん効果もまったく異なったものが多くあります。今回示す手法を応用すれば、前回紹介したドキュメントを参照しながら、ほかのフィルターもいろいろと切り替えて試せるようになるはずです。
スライダーとスイッチを追加する
今回のプログラムは、前回の成果からスタートします。まずは、フィルターのパラメータを設定したり、フィルターそのものを切り替えるためのスライダーとスイッチを追加します。iOSのUIKitに含まれるクラスで言えば、それぞれUISliderとUISwitchですね。これらのオブジェクトを作成するコードを、前回に定義したCamViewControllerの先頭部分に加えておきます。
それらのオブジェクトの必要な属性の初期化は、やはりviewDidLoadメソッドの中で実行します。
スライダーについては、まずisContinuousをfalseに設定しています。これにより、ユーザーがスライダーをドラッグしている最中には、フィルター処理が始まらないようにしています。そして、最終的にスライダーの値が変化すると、このビューコントローラー内にあるfilterImageメソッドを呼び出して、フィルター処理を実行するように設定します。つまり、ユーザーが指をスライダーのツマミから離した時に、初めてその値の設定でフィルターをかけるわけです。
スイッチは、オンにした時の溝の色を茶色に設定しています。もちろんこれは必須ではありませんが、デフォルトの緑色が、なんとなく今回の機能には不似合いなので、変更してみました。ユーザーがスイッチを操作すると、スライダーと同じfilterImageメソッドを呼び出すようにしています。これは誤りではありません。その同じメソッドの中で、スライダーの値やスイッチの状態を読み取って、適宜処理しているからです。
今回追加したスライダーとスイッチのレイアウトは、やはりviewWillLayoutSubviewsメソッドの中で設定します。
前回に配置した入力と出力の2つの画像の間に滑り込ませるように置いてみました。スライダーは長さを指定しなければならないので、いつものようにフレームをCGRectで指定しています。一方、スイッチは最初から大きさが決まっているので、原点を表すoriginを、CGPointで指定しています。
また、その下にあるイメージピッカーコントローラーのdidFinishPickingMediaWithInfoメソッドの中では、前回には書いていてたfilterImageメソッドの呼び出しを削除しました。これにより写真を撮影しただけではフィルターは呼び出されなくなります。
肝心のフィルター処理メソッドfilterImageの中では、スイッチの状態によって、CIEdgesとCIEdgeWorkのフィルターを切り替えています。その際に、スライダーの値を読み取って、パラメータも設定しています。スライダーの値の範囲は、デフォルトのままなので、0.0~1.0です。ここでは、その値に適当な係数を掛けたり足したりして、だいたい適切と思われる値の範囲に調整しています。CIEdgesは、効果の色の強さを0から300の範囲で設定できることになります。CIDegeWorkでは半径(線の太さ)を指定しますが、値の範囲は1から11ということになります。
フィルターへ入力する画像の指定をはじめとして、2つのフィルターに共通の処理は、なるべく1回の記述で済むようにしています。
この連載の記事
- 第100回 SceneKitの物理現象シミュレーションとアニメーションをARKitに持ち込む
- 第99回 「物理学体」と「物理学場」を設定して物理現象をシミュレーション
- 第98回 SceneKitのノードに動きを加えるプログラム
- 第97回 いろいろな形のノードをシーンの中に配置する
- 第96回 SceneKitの基礎シーンビュー、シーン、ノードを理解する
- 第95回 現実世界の床にボールや自動車のモデルを配置する
- 第94回 ARKitを使って非現実世界との融合に備える
- 第93回 ARKitが使えるiPadを識別するプログラム
- 第92回 Swift Playgrounds 2.1での問題点をまとめて解消する
- 第91回 iPadの内蔵カメラで撮影した写真を認識するプログラム
- この連載の一覧へ