何とも地味なテーマですが、色処理まわりは技術的にだいぶ枯れており、実装でやりたいこともある程度パターン化されています。ゆえに便利なOSSが多く出揃っている部分でもあります。
今回はそんな色処理まわりの便利なOSSを3種類紹介します。
グラデーション描画のヘルパークラスLBGradient
CocoaにはNSGradientというグラデーション描画用のクラスがあるのですが、iOSにはそれがないため、
このようなグラデーションを描こうと思ったらCore Graphicsを用いて
こんなに長いコードを書く必要があります。
コードをよく見れば、UIGraphicsGetCurrentContext()をはじめCore Graphicsではおなじみの手続きが多く占めているものの、このコードをサラサラと書けるかというとなかなか辛いものがあります。
そこでLBGradientというクラスを使うと、この部分がこんなにシンプルになります(実行結果は上と同じ)。
LBGradientクラスのinitWithColorsAndLocations:というメソッドが可変長引数をとるようになっていて、ここにグラデーションの基準となる色と位置をセットで複数個指定します。グラデーションを指定するためのAPIとしては直観的でわかりやすいのではないでしょうか。
上記ではグラデーションの描画にdrawInRect:angle:を用いて「指定した矩形内を指定した角度でグラデーション描画」していますが、他にも次のようなメソッドも用意されており、
任意のベジェ曲線に沿ってグラデーションを描画することも可能です。
LBGradientのソースを見ると、initWithColorsAndLocations:メソッドではグラデーション基準点の色と位置の配列を生成し、描画メソッド内でCGGradientCreateWithColorsメソッドとCGContextDrawLinearGradientメソッドを用いてグラデーション描画していて、要するに最初に載せた長いコードをうまくラップしてくれている、ということがわかります。
LBGradientのリポジトリのURLは以下になります。
サクッとグラデーションをかけて色をつけたい、といった場合にいかがでしょうか。
Core Graphics のややこしい手続きをラップするクラスを自作する際の参考としてもよいかと思います。
2つのUIColorの間でクロスフェードさせるUIColorのカテゴリ
UIColor-CrossFaceを使うと、指定した比率で2つのUIColorの間でクロスフェードさせることができます。
……と文章で書いても何のことかわかりにくいと思うので、まずは下記URLからソース一式をダウンロードし、“UIColorCrossFadeDemo”というプロジェクトをビルド&実行してみてください。
このような画面が現れ、画面内のスライダーを右に動かすと、以下のようにスライダーの値に従って背景が赤から青へクロスフェードします。
これは、Flashで言えばシンボルの「カラー効果」プロパティに値を指定して色を変えることに相当していて、こういったことを実現するためのUIColorのカテゴリが、UIColor-CrossFaceです。
APIもとてもわかりやすく
最初の色、最後の色をUIColor型で指定し、あとは比率を指定すれば、「最初の色から最後の色までクロスフェードする際の指定比率における色」が返されます。
サンプルコードではこのratio引数に渡す値としてスライダーの値を用いていますが、たとえば本連載の第1回でご紹介したトゥイーンライブラリを用いることで、イージング付きでクロスフェードするアニメーションを実現することもできます。
ちなみに、APIには、
といったように、比率を直接渡すのではなく、比率を求める計算式を渡すためのメソッドも用意されているので、カスタムイージングカーブを実現するための式を自作して渡すことも可能です。
カテゴリ内部で色の計算を行っている部分の実装は、下記のようになっています。
最初の色、最後の色それぞれのcolor components(RGBAの各値)を取り出し、各チャネルごとに指定比率でのブレンドを行う、というシンプルなものです。
ところで、実はこのカテゴリを使用しなくても、Core Animationを用いれば、CALayerの backgroundColorやshadowColorなどは、下記のようなコードで色のクロスフェードを実現できてしまいます。
ただ、この方法はあくまでCore Animationでアニメーション可能なプロパティ※をアニメーションさせたい場合にしか用いることができないので、UIColor型であればどんなプロパティに対しても適用可能なUIColor-CrossFadeのほうが汎用性は高いと言えます(たとえば、サンプルにあったようにスライダーの値に合わせて色を変化させたい場合や、UILabelのtextColorプロパティに適用したい場合など)。
今回紹介したUIColor-CrossFade自体は、たった百数行のシンプルなものですが、この発想を応用し、色んな自前パラメータをアニメーションさせるカテゴリを自作してみても楽しいかもしれません。
色の重ね合わせやCSSカラー名での色の指定ができるようになるUIColorのカテゴリ
最後に、UIColorの便利な拡張機能を色々と詰め合わせたカテゴリ“uicolor-utilities”を紹介します。
たとえば、UIColorのカテゴリやマクロでは定番の、16進カラーコード(Hexカラー)との相互変換機能も、UInt32型、NSString型両方に対応して備えています。
色の重ね合わせ機能も備えており、PhotoshopやFireworksのブレンドモードではおなじみの、乗算、加算、比較(暗)、比較(明)といった計算方法別にメソッドが用意されています。
ちょっとした機能ですが、次のようなメソッドも持っています。
この内部実装は下記のようになっており、チャネルごとの値を(チャネル数を判別して)NSString型で出力してくれるので、ログ出力に便利です。
下記メソッドでは、輝度成分を抽出しグレースケール化したUIColorを返します。
「輝度」の求め方は諸々あるのですが、ソースで確認したところ、RGB にかけている係数の値から、YPbPr の計算式に基づいているようです。
“aliceblue”や“antiquewhite”などのCSSカラー名からUIColorを取得できるメソッドも備えています。
UIColor の標準メソッドではblackColorやredColorなどごくごく基本的な色を出力する機能しかなく、もうちょっと違う色味を出したいとなると直接RGB値から生成するしかありませんでした。CSSカラーはWeb上にたくさんの色見本があるので、Webで気に入った色を探しつつそのまま色名を指定する、といったことができるようになります。そして、RGB値を指定する場合よりソースコードから色味を想像しやすいというメリットもあります。
uicolor-utilitiesは下記URLよりダウンロードできます。
まとめ
今回は「色処理関連の便利OSS」という括りで、グラデーション描画のヘルパークラスLBGradient、2つのUIColorの間でクロスフェードさせるUIColorのカテゴリUIColor-CrossFace、色の重ね合わせやCSSカラー名での色の指定ができるようになるUIColorのカテゴリuicolor-utilitiesの3つのOSSを紹介しました。
今回ご紹介したOSSではそれほど複雑な機能を代行してくれているわけではないのですが、そのぶん内部のソースコードも把握しやすく、使い回しや応用がききやすいのではと思います。モック開発時などにサクッといい感じに色をつけたい場合に、あるいはヘルパークラスを自作する際の参考に、何かしらの形で皆様の開発のお役に立てば幸いです。