128
Core Image Tips & Tricks in iOS 9 Shuichi Tsutsumi @shu223 iOS 9 Bootcamp2015.10.7

Core Image Tips & Tricks in iOS 9

Embed Size (px)

Citation preview

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 の話

1. ブラー

ブラーとは?

ブラーとは?

ブラーとは?

ブラーとは?

画像をぼかす処理のこと

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

Original Box

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 以前

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

iOS 8• CIKernel

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

iOS 9• CIFilter

iOS 9• CIFilter

- CIBoxBlur

- CIDiscBlur

- CIMotionBlur

- CIZoomBlur

(Motion / Zoom は実際には 8.3 から)

ポイント

ポイント• CIFilterはGPUで処理される

ポイント• CIFilterはGPUで処理される

• 実装は超簡単

ポイント• CIFilterはGPUで処理される

• 実装は超簡単

→ iOS 9 では、

• 多様なブラー(Box, Gaussian, Motion…)を

• 高速(by GPU)かつ

• 手軽(ビルトイン)に

利用できるようになった

こういう表現がしやすくなった

2. 画面遷移アニメーション

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 への直接出力も可能に

MetalKit

MetalKit

• GLKit の GLKView ライクに、MetalKit の MTKView に

CIFilter の処理結果を直接描画可能に

→ Metal でフィルタをかけて Metal で描画!

まとめ• iOS 9 では CIFilter にブラー系のビルトインフィルタがいくつか追加された

- GPU で高速処理されるブラーフィルタが手軽に使えるようになった!

- Apple も大好きなブラーを使った UI が実現しやすくなった!

• そんな Core Image のブラー系フィルタを画面遷移のカスタムアニメーションに使ってみるといいかも

• iOS 9 で追加された MetalKit および Core Image の Metal 連携でさらにヌルッとしたアニメーションを実現できるかも