木版画のようなタッチと、線画化の効果を試してみる
ここまでできたら、とりあえず効果を確かめてみましょう。適当に写真を撮影してから、まずスライダーを動かしてみます。すると、木版画調に加工された画像が撮影した元の画像の下に表示されます。
スライダーを右に動かすほど、荒い「彫り」になります。撮影する内容によっては、棟方志功の木版画のようなタッチになるかもしれません。
スイッチにタッチしてオンにすると、撮影した画像の輪郭を抽出したような効果の画像が表示されます。
このフィルターでは、白黒が反転したモノクロ画像のように見える場合もありますが、派手めの色調の写真を撮影すれば、結果にもそれなりに色が付きます。効果の色は元の色に近い色になるとは限りませんが、必ずしも反転するわけではないのが面白いところです。このフィルターの場合、スライダーが左端にあると、ほとんど何も表示されないので、右の方に動かしてみてください。
ほぼリアルタイムでフィルターがかかるように工夫する
はじめに述べたように、パラメータの調整用に配置したスライダーでは、isContinuousをfalseに設定していました。それによって、スライダーを操作中には、値が変化してもフィルター処理メソッドが呼ばれないようにしているのです。そうした訳は、フィルターの処理にはそれなりに時間がかかるので、スライダーが動いている最中に毎回呼び出されると、動きがカクカクしてしまうからです。しかしユーザーからすれば、スライダーを動かしながら、効果の変化を見たいところです。それをスムーズな表示で可能にするには、今よりもずっと処理速度の速いiPadの登場を待つか、実質的なフィルター処理の時間を短縮する方法を考えればいいのです。
このプログラムでは、撮影した画像も、それを加工した画像も、画面の中のかなり狭い領域に表示しています。つまり、表示するだけなら、実際に必要な画像の解像度は、撮影した画像よりもかなり少なくても構わないのです。
そこで、撮影した写真画像を、あらかじめ小面積での表示用の低解像度に変換しておくことで、フィルター処理の時間を短縮することにしました。iOSでは、画像の解像度を変換する方法はさまざまなものが考えられます。ここではついでなので、Core Imageのフィルターとして用意されているLanczos Scale Transformを使うことにしました。
まずそのための下準備として、解像度変換した画像を保持しておくためのCIImageクラスのオブジェクトorgImageを、クラス定義の先頭に付け加えます。
また、スライダーのisContinuous属性をtrueに設定して、スライダーのツマミの操作中もフィルター処理が起動されるようにしています。
実際の解像度変換処理は、イメージピッカーコントローラーのdidFinishPickingMediaWithInfoメソッドの中に組み込んで、撮影する都度、自動的に解像度が変換されるようにします。
iPadのカメラは、かなり高解像度なので、ここでは、元の10分の1の解像度となるように、スケールを決めるパラメータの値を0.1に設定しています。変換後の画像は、撮影したままの画像の代わりに、画面の上下のイメージビューに張り付けておきます。
あとの処理は、基本的に変わりませんが、1つだけ修正しておくべきところがあります。それは、EdgeWorkフィルターの半径パラメータです。このフィルターは、パラメータの値が同じでも、画像の解像度によって効果の見え方が大きく変わってしまうからです。画像の解像度を低くしたら、それに合わせて半径も小さくする必要があります。ここでは、スライダーによって0.2から1.2の範囲でパラメータの値が変化するように変更しました。
以上のようなプログラムの変更による動作の変化は、もはや細かく説明する必要はないでしょう。スライダーを動かしている最中もフィルター結果の画像がアップデートされるようになれば成功です。実行結果の画面は上の例と何も変わらないので特に示しませんが、各自スライダーを動かして確認してみてください。
次回の予定
Core Imageフィルターは、非常に種類が多いので、とてもすべてを試してみるわけにはいきません。また、1つのプログラムでいろいろなフィルターを切り替えられるようにするには、それなりにユーザーインターフェースが複雑になり、プレイグラウンド向きではなくなってしまいます。次回は、多い、多いと言われるCore Imageフィルターの種類が、実際にどれだけあるのか、テーブルビューを使って一覧表示してみます。そこから、それぞれのフィルターのパラメータの説明も見られるようにするプログラムを作ってみることにしましょう。