Core Image Tips & Tricks in iOS 9
Shuichi Tsutsumi @shu223 iOS 9 Bootcamp(2015.10.7)
自己紹介• iOS専業フリーランスエンジニア
• ブログ『Over&Out その後』
• GitHub: shu223 『iOS-9-Sampler』
• 著書
- 「iOSアプリ開発 達人のレシピ100」
- 「iOS×BLE Core Bluetooth プログラミング」
• クラスメソッド田宮さんとは13年前の就活時にグループ面接で出会った
- 4年前、iOSの勉強会で偶然再開
- 昨年クラスメソッドに入社したとのことでランチ行った
概要iOS 9 の Core Image の新機能について話します
フィルタが増えました!
Original
フィルタが増えました!
CICrystallizeOriginal
フィルタが増えました!
CIPointillizeOriginal
フィルタが増えました!
Original CICircularWrap
フィルタが増えました!
CIKaleidoscopeOriginal
本発表の方針• 新フィルタの紹介
• 飛び道具的なものは省き、なるべく実用的な話をします
本発表の方針• 新フィルタの紹介
• 飛び道具的なものは省き、なるべく実用的な話をします
1. Apple も UI で多用する「ブラー」の話
本発表の方針• 新フィルタの紹介
• 飛び道具的なものは省き、なるべく実用的な話をします
1. Apple も UI で多用する「ブラー」の話
2. Core Image を画面遷移のカスタムアニメーションに使う話
本発表の方針• 新フィルタの紹介
• 飛び道具的なものは省き、なるべく実用的な話をします
1. Apple も UI で多用する「ブラー」の話
2. Core Image を画面遷移のカスタムアニメーションに使う話
3. ヌルッとしたアニメーションを実現するための Metal の話
ブラーとは?
画像をぼかす処理のこと
iOS におけるブラーを用いた表現
iOS におけるブラーを用いた表現コントロールパネル
- オーバーレイするパネルの背景にブラー
- いわゆる「磨りガラス効果」
iOS におけるブラーを用いた表現3D Touch - Quick Actions
- 周囲のアイコンがタッチの強さに応じてボケていき、ショートカットメニューが表示される
iOS におけるブラーを用いた表現3D Touch - Live Photo 再生
- 静止画と動画のつなぎにブラーを利用
iOS におけるブラーを用いた表現Spotlight
- 下方向に画面をドラッグすると検索窓が出てくる
- 遷移の進行に応じてホーム画面がボケていく
• Appleも積極的に「ブラー」をUIに利用
• Appleも積極的に「ブラー」をUIに利用
• (デザイナーさんから提示される)デザイン案にブラーが用いられることも多い
• Appleも積極的に「ブラー」をUIに利用
• (デザイナーさんから提示される)デザイン案にブラーが用いられることも多い
→ iOS アプリの UI においてブラーを用いた表現は重要!
• Photoshop で利用可能なブラー(の一部)
- Box Blur
- Gaussian Blur
- Radial Blur (Zoom)
- Lens Blur
- Motion Blur
- Shape Blur
- Tilt-Shift
ブラーの種類
Original Box Gaussian
Original Box Gaussian Zoom
• ぼけ方が違い、用途が違う
- カーネルの形状や分布が違うもの
• ぼけ方が違い、用途が違う
- カーネルの形状や分布が違うもの
- カーネルを動的に決定するもの
• ぼけ方が違い、用途が違う
- カーネルの形状や分布が違うもの
- カーネルを動的に決定するもの
- 複合的な処理をするもの
• ぼけ方が違い、用途が違う
- カーネルの形状や分布が違うもの
- カーネルを動的に決定するもの
- 複合的な処理をするもの
→ ブラーにもいろいろある
カーネルと畳み込み処理• ブラー処理:周囲の画素との平均値を取るカーネル(オペレータ/Weights とも呼ばれる)を畳み込む
カーネルと畳み込み処理• ブラー処理:周囲の画素との平均値を取るカーネル(オペレータ/Weights とも呼ばれる)を畳み込む
• カーネルサイズと画像サイズに応じて処理量が指数関数的に増大する
カーネルと畳み込み処理• ブラー処理:周囲の画素との平均値を取るカーネル(オペレータ/Weights とも呼ばれる)を畳み込む
• カーネルサイズと画像サイズに応じて処理量が指数関数的に増大する
カーネルサイズ3x3、画像サイズ2448x3264の場合:演算回数7191万回 カーネルサイズが7x7だと、3億9152万回!
→ブラーおよび畳み込み処理はシンプルだが処理の負荷は大きい
動的にブラー処理を行う必要があるケース
動的にブラー処理を行う必要があるケース
例:Spotlight 画面への遷移
動的にブラー処理を行う必要があるケース
例:Spotlight 画面への遷移
• 動的にキャプチャ取得
動的にブラー処理を行う必要があるケース
例:Spotlight 画面への遷移
• 動的にキャプチャ取得
• 遷移進行状況に応じてボケ度合いを変えたブラー処理
動的にブラー処理を行う必要があるケース
例:Spotlight 画面への遷移
• 動的にキャプチャ取得
• 遷移進行状況に応じてボケ度合いを変えたブラー処理
+ 処理結果を描画(画面に表示)
動的にブラー処理を行う必要があるケース
例:Spotlight 画面への遷移
• 動的にキャプチャ取得
• 遷移進行状況に応じてボケ度合いを変えたブラー処理
+ 処理結果を描画(画面に表示)
• 60FPSなら0.016秒ごとに畳み込み演算処理+描画を行う必要がある
• ユーザーのジェスチャの処理をブロックしてはいけない
• ユーザーのジェスチャの処理をブロックしてはいけない
• ブラー処理を行いその出力結果を即時描画しないといけないので、バックグラウンドで非同期処理というわけにもいかない
• ユーザーのジェスチャの処理をブロックしてはいけない
• ブラー処理を行いその出力結果を即時描画しないといけないので、バックグラウンドで非同期処理というわけにもいかない
• ある程度のFPSで処理しないと「ヌルッ」とした感じにならない
• ユーザーのジェスチャの処理をブロックしてはいけない
• ブラー処理を行いその出力結果を即時描画しないといけないので、バックグラウンドで非同期処理というわけにもいかない
• ある程度のFPSで処理しないと「ヌルッ」とした感じにならない
→ GPU Acceleration が必須!
いったん整理• iOS アプリの UI においてブラーを用いた表現は重要
いったん整理• iOS アプリの UI においてブラーを用いた表現は重要
• ブラーにもいろいろある
いったん整理• iOS アプリの UI においてブラーを用いた表現は重要
• ブラーにもいろいろある
• ブラー処理の肝である畳み込み演算処理は負荷が大きい
いったん整理• iOS アプリの UI においてブラーを用いた表現は重要
• ブラーにもいろいろある
• ブラー処理の肝である畳み込み演算処理は負荷が大きい
• 遷移アニメーション等、動的な処理が必要な場合、GPU
Acceleration が必須
iOSにおけるブラー実装方法の近代史
iOS 7 以前
Core Graphics CPUでの処理になるので当然重い 実装が面倒/自分で要最適化
iOS 7 以前
Core Graphics CPUでの処理になるので当然重い 実装が面倒/自分で要最適化
OpenGLシェーダ CIKernelがまだないのでOpenGLの知識が必要
iOS 7 以前
Core Graphics CPUでの処理になるので当然重い 実装が面倒/自分で要最適化
OpenGLシェーダ CIKernelがまだないのでOpenGLの知識が必要
vImage 実装が面倒/情報も少ない
iOS 7 以前
Core Graphics CPUでの処理になるので当然重い 実装が面倒/自分で要最適化
OpenGLシェーダ CIKernelがまだないのでOpenGLの知識が必要
vImage 実装が面倒/情報も少ない
Core Image CIGaussianBlurしかない
iOS 7 以前
Core Graphics CPUでの処理になるので当然重い 実装が面倒/自分で要最適化
OpenGLシェーダ CIKernelがまだないのでOpenGLの知識が必要
vImage 実装が面倒/情報も少ない
Core Image CIGaussianBlurしかない
UIToolBarを流用 邪道
iOS 7 以前
Core Graphics CPUでの処理になるので当然重い 実装が面倒/自分で要最適化
OpenGLシェーダ CIKernelがまだないのでOpenGLの知識が必要
vImage 実装が面倒/情報も少ない
Core Image CIGaussianBlurしかない
UIToolBarを流用 邪道
GPUImage サードパーティ製/コードでかい
iOS 8• CIKernel
- GPUで処理される高速フィルタを自作し、CIFilterとして扱えるようになった
iOS 8• CIKernel
- GPUで処理される高速フィルタを自作し、CIFilterとして扱えるようになった
- Shading Language の知識が必要
iOS 8• CIKernel
- GPUで処理される高速フィルタを自作し、CIFilterとして扱えるようになった
- Shading Language の知識が必要
• UIEffect
iOS 8• CIKernel
- GPUで処理される高速フィルタを自作し、CIFilterとして扱えるようになった
- Shading Language の知識が必要
• UIEffect
- 「磨りガラス効果」が簡単にできるように
iOS 8• CIKernel
- GPUで処理される高速フィルタを自作し、CIFilterとして扱えるようになった
- Shading Language の知識が必要
• UIEffect
- 「磨りガラス効果」が簡単にできるように
- ただ明るい/暗いしか開発者は選択の余地がない(ぼけ具合すらコントロールできない)
iOS 9• CIFilter
- CIBoxBlur
- CIDiscBlur
- CIMotionBlur
- CIZoomBlur
(Motion / Zoom は実際には 8.3 から)
ポイント• CIFilterはGPUで処理される
ポイント• CIFilterはGPUで処理される
• 実装は超簡単
ポイント• CIFilterはGPUで処理される
• 実装は超簡単
→ iOS 9 では、
• 多様なブラー(Box, Gaussian, Motion…)を
• 高速(by GPU)かつ
• 手軽(ビルトイン)に
利用できるようになった
CIFilterのトランジションカテゴリ
CIFilterのトランジションカテゴリ• CICategoryTransition
CIFilterのトランジションカテゴリ• CICategoryTransition
- iOS では 6 から利用可能に
CIFilterのトランジションカテゴリ• CICategoryTransition
- iOS では 6 から利用可能に
• トランジション=遷移
CIFilterのトランジションカテゴリ• CICategoryTransition
- iOS では 6 から利用可能に
• トランジション=遷移
• スライドショーの画像間や、動画のシーン切り替え用途で用意されたもの
参考OSS:CoreImageTransition
参考OSS:CoreImageTransition
参考OSS:CoreImageTransition
• https://github.com/shu223/CoreImageTransition
• CICategoryTransition のフィルタ9種類を試せるサンプル
• 解説記事:http://d.hatena.ne.jp/shu223/20130311/1362962817
iOS 9 で追加されたトランジション
CIPageCurlTransition CIPageCurlWithShadowTransition CIRippleTransition
iOS 9 で追加されたトランジション
CIPageCurlTransition CIPageCurlWithShadowTransition CIRippleTransition
iOS 9 で追加されたトランジション
CIPageCurlTransition CIPageCurlWithShadowTransition CIRippleTransition
iOS 9 で追加されたトランジション
CIPageCurlTransition CIPageCurlWithShadowTransition CIRippleTransition
UIKit カスタム画面遷移
× Core Image トランジション
カスタム画面遷移• iOS 7 より、UINavigationController やモーダル表示による画面遷移アニメーションを簡単に自作できるようになった
参考OSS:AnimatedTransitionGallery
• https://github.com/shu223/AnimatedTransitionGallery
• 53種類のカスタム画面遷移を試せるサンプルコード
• 解説記事:http://d.hatena.ne.jp/shu223/20140416/1397608824
カスタム画面遷移 × Core Imageトランジション
カスタム画面遷移 × Core Imageトランジション
スナップショット取得
カスタム画面遷移 × Core Imageトランジション
スナップショット取得
スナップショットに対して Core Image のトランジションエフェクトをかける
AnimatedTransitionGallery/CoreImageTransitions
https://github.com/shu223/AnimatedTransitionGallery/tree/master/CoreImageTransitions
AnimatedTransitionGallery/CoreImageTransitions
https://github.com/shu223/AnimatedTransitionGallery/tree/master/CoreImageTransitions
AnimatedTransitionGallery/CoreImageTransitions
https://github.com/shu223/AnimatedTransitionGallery/tree/master/CoreImageTransitions
AnimatedTransitionGallery/CoreImageTransitions
https://github.com/shu223/AnimatedTransitionGallery/tree/master/CoreImageTransitions
→ UINavigationController の push / pop 時やモーダル遷移時の遷移アニメーションに、Core Image のトランジションエフェクトを使ってみた
・・・ものの、
クセが強すぎて普通のアプリで使うにはちょっと・・・
CICategoryTransition以外のフィルタでもOK
CICategoryTransition以外のフィルタでもOK
• Transitionカテゴリのフィルタの特徴は、「時間」の概念(kCIInputTimeKey)があること
CICategoryTransition以外のフィルタでもOK
• Transitionカテゴリのフィルタの特徴は、「時間」の概念(kCIInputTimeKey)があること
- 経過時間に応じてエフェクトのかかり具合が進行していく
CICategoryTransition以外のフィルタでもOK
• Transitionカテゴリのフィルタの特徴は、「時間」の概念(kCIInputTimeKey)があること
- 経過時間に応じてエフェクトのかかり具合が進行していく
→kCIInputTimeKey がなくても、経過時間を何らかのパラメータに割り振ればOK
UIKit カスタム画面遷移
× Core Image ブラー
例1:CIBoxBlur方針
• 遷移の経過時間に応じて kCIInputRadius を設定
https://github.com/shu223/AnimatedTransitionGallery/tree/master/CoreImageTransitions
例2:CIMotionBlur方針
• 遷移の方向を kCIInputAngle に適用
• 移動量に応じて kCIInputRadius を設定(早く移動するほどボケる)
https://github.com/shu223/AnimatedTransitionGallery/tree/master/CoreImageTransitions
• 遷移方向に
• 移動量に応じた強さで
ボケる
→ 遷移のスピード感を表現
3. Core Image × Metal
Metal• OpenGL に代わるローレベルのグラフィックAPI
• OpenGL は多くのハードをサポートするために、特定のハードの性能を限界まで引き出せていなかった
• Metal は Apple のハードに特化しているため、最大で
OpenGL の10倍速い(by Apple)
Core Image × Metal
CIFilter のビルトインフィルタ(のいくつか)は Metal
Performance Shader を利用
Core Image × Metal
MTLTexture から CIFilter への直接入力、CIFilter から
MTLTexture への直接出力も可能に
• GLKit の GLKView ライクに、MetalKit の MTKView に
CIFilter の処理結果を直接描画可能に
→ Metal でフィルタをかけて Metal で描画!
まとめ• iOS 9 では CIFilter にブラー系のビルトインフィルタがいくつか追加された
- GPU で高速処理されるブラーフィルタが手軽に使えるようになった!
- Apple も大好きなブラーを使った UI が実現しやすくなった!
• そんな Core Image のブラー系フィルタを画面遷移のカスタムアニメーションに使ってみるといいかも
• iOS 9 で追加された MetalKit および Core Image の Metal 連携でさらにヌルッとしたアニメーションを実現できるかも