[iOS][Mac] Core Graphics - グラデーション

2011年6月28日火曜日 | Published in , | 0 コメント

CoreGraphics の グラデーションについての覚書き。



Linear Gradient


2つの点を指定してその間でグラデーションを表現する方式。

CGGradientRef() で定義し、CGContextDrawLinearGradient() で描画する。あらかじめ描画したい形(パス)を登録しておく。コードはこんな感じ。
- (void)drawRect:(CGRect)rect
{
 CGContextRef context = UIGraphicsGetCurrentContext(); 
 CGContextSaveGState(context);
 
 CGContextAddRect(context, self.frame);
 
 CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
 CGFloat components[] = {
 1.0f, 1.0f, 1.0f, 0.5f, // R, G, B, Alpha
 0.0f, 0.0f, 0.0f, 0.5f
 };
 CGFloat locations[] = { 0.0f, 1.0f };
 size_t count = sizeof(components)/ (sizeof(CGFloat)* 4);
 
 CGRect frame = self.bounds;
 CGPoint startPoint = frame.origin;
 CGPoint endPoint = frame.origin;
 endPoint.y = frame.origin.y + frame.size.height;
 
 CGGradientRef gradientRef =
 CGGradientCreateWithColorComponents(colorSpaceRef, components, locations, count);
 
 CGContextDrawLinearGradient(context,
 gradientRef,
 startPoint,
 endPoint,
 kCGGradientDrawsAftersEndLocation);
 
 CGGradientRelease(gradientRef);
 CGColorSpaceRelease(colorSpaceRef);
 
 CGContextRestoreGState(context);
}

startPoint, endPoint はグラデーションの開始位置、終了位置を決める。例えば左上から左下にした場合はこう。

左上から右上。

左上から右下。

例では2色間のグラデーションを使っているが複数色間のグラデーションを作ることもできる。その場合は上記コードの components に色情報を増やす。
CGFloat components[] = {
 1.0f, 1.0f, 1.0f, 0.5f,
 1.0f, 0.0f, 0.0f, 0.5f,
 :
 0.0f, 0.0f, 0.0f, 0.5f
 };
components を増やした場合は locations の要素もそれに合わせて増やす。locations は各色の割合を表していて 0〜1 の数値を取る。例えば
CGFloat locations[] = { 0.0f, 0.2f, 1.0f };
とすると全体の描画対象の 0〜20% が1色目と2色目のグラデーション、20%〜100%の領域が2色目と3色目のグラデーションになる。等間隔にしたい場合は CGGradientCreateWithColorComponents() の locations に NULLを渡すこともできる。


Radial Gradient


放射状のグラデーションを表現する。

こちらも2点を指定しその間のグラデーションを表現するが、Linearと違うのは各点から放射状にグラデーションがかかること。コードはこんな感じ。
- (void)drawRect:(CGRect)rect
{
 CGContextRef context = UIGraphicsGetCurrentContext(); 
 CGContextSaveGState(context);
 
 CGContextAddEllipseInRect(context, self.frame);
 
 CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
 CGFloat components[] = {
 1.0f, 1.0f, 1.0f, 1.0f,
 0.5f, 0.5f, 0.5f, 1.0f,
 0.25f, 0.25f, 0.25f, 1.0f,
 }; 
 CGFloat locations[] = { 0.0, 0.5, 1.0 };
 
 size_t count = sizeof(components)/ (sizeof(CGFloat)* 4);
 CGGradientRef gradientRef =
 CGGradientCreateWithColorComponents(colorSpaceRef, components, locations, count);
 
 CGRect frame = self.bounds;
 CGFloat radius = frame.size.height/2.0*0.8;
 CGPoint startCenter = frame.origin;
 startCenter.x += frame.size.width/2.0;
 startCenter.y += frame.size.height/2.0;
 CGPoint endCenter = startCenter;
 
 CGFloat startRadius = 0;
 CGFloat endRadius = radius;
 
 CGContextDrawRadialGradient(context,
 gradientRef,
 startCenter,
 startRadius,
 endCenter,
 endRadius,
 kCGGradientDrawsAfterEndLocation);
 
 CGGradientRelease(gradientRef);
 CGColorSpaceRelease(colorSpaceRef);
 
 CGContextRestoreGState(context);
}
CGGradientRef の作り方は Linear と同じ。ポイントは2つの点とそれらの点を中心として描かれる円の半径を指定するところ。例では startCenter と endCenter を同じにしているので中心から放射状にグラデーションがかかっているように見える。startRadius は 0。

次は startCenter を左上に動かした例。
擬似 3D ぽい画像になる(見かたを変えると遠くでライトを光らせているようにも見える)。


サンプル


GitHub からどうぞ。

GradientSample at 2011年06月28日 from xcatsan/iOS-Sample-Code - GitHub

なお背景には標準で付いていた "Scroll View Textured Background Color" を使っている(これ自体を描画しているわけではない)



参考情報


Gradients
Gradientsの解説はマニュアルが詳しい。


A-Liaison BLOG: CGGradientを用いてUITableViewCellを描画し、テーブルをカッコよく見せる方法
UIColor 元にグラデーションを作るアイディアが面白い。

(旧) Cocoaの日々: NSGradiation
Mac OS X ならこっちも使える。

Responses

Leave a Response

[フレーム]

人気の投稿(過去 30日間)

  • 2011年06月09日 追記  UITableViewCell の Identifier 設定を忘れてたので追記しました。 UINib を使うと簡単に Nib で定義した UITableViewCell が使える。 今回のサンプル: [関連] Cocoaの日々: [iO...
  • Asset Catalogには画像以外のデータも置ける。サウンドファイル(.aif)を置いてみた。 取り出すには NSDataAsset を使う。 let sound = NSDataAsset(name: name) // use sound.data 取り出したサウ...
  • Core Data を使ったアプリケーションで下のような検索機能を実装している。 設定された値を元に NSPredicate を作成し、Core Data に対して検索をかけるのだが、こういう場合に NSCompoundPredicate が役に立つ。 NSCompound...
  • UIImage からサムネイル用途で使用する縮小画像を作る。 縮小処理 こんな感じ。 @implementation UIImage (extension) - (UIImage*)imageByShrinkingWithSize:(CGSize)size { CGF...
  • [前回] Cocoaの日々: [Mac] NSArrayController に Undo/Redo を実装する [4] 初期値ありの場合 選択状態も Undo/Redo してみる。 選択状態の Undo/Redo NSArrayController の選択に関係するメ...

AltStyle によって変換されたページ (->オリジナル) /