はじめの前に
はじめに、
2010年6月17日、
Windows Phone 7が発表された際に
Windows Phone 7が発売されているだろう2011年下半期には、
こちらに関しては、
Visual Studio 2010では、
はじめに
さて、
どのような処理を行っているのかをグラデーションさせた円形の描画を例にして、
グラデーション掛かった円形を描画するメソッドを実装する
先にソースコードを示します。コメントの部分で数字を打っておきましたので、
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
namespace GradientionSample
{
public class GraphicsExtension
{
public static Color KeyColor = Color.FromArgb(255, 0, 255);
public static void DrawGradientEllipse(Graphics g, Rectangle rc,
Color startColor, Color endColor, Color borderColor,
FillDirection gradientType)
{
// クリッピング用の色の設定
Color clippingColor = Color.Green;
Rectangle rect = new Rectangle(0, 0, rc.Width, rc.Height);
// (1)グラデーションを描画するイメージの生成
Bitmap gradientImage = new Bitmap(rc.Width, rc.Height,
PixelFormat.Format16bppRgb565);
Graphics gxGradient = Graphics.FromImage(gradientImage);
// グラデーションを描画する
GradientFill.Fill(gxGradient, rect,
startColor, endColor, FillDirection.TopToBottom);
// (2)任意の図形でグラデーションを切り抜く為のイメージの生成
Bitmap tempImage = new Bitmap(rc.Width, rc.Height,
PixelFormat.Format16bppRgb565);
// クリッピング用に緑色の円形を描画するdelegateを呼ぶ
Graphics gxTemp = Graphics.FromImage(tempImage);
gxTemp.Clear(KeyColor);
gxTemp.FillEllipse(new SolidBrush(clippingColor), rect);
if (borderColor != Color.Empty)
{
gxTemp.DrawEllipse(new Pen(borderColor), rect);
}
// グラデーションイメージに対して、
// クリッピング用のイメージを、緑色の透過色を使用して上書きする
ImageAttributes clippingAttr = new ImageAttributes();
clippingAttr.SetColorKey(clippingColor, clippingColor);
gxGradient.DrawImage(tempImage,
rect, 0, 0, rect.Width, rect.Height,
GraphicsUnit.Pixel, clippingAttr);
// (3)グラデーションの掛かった図形を描画する
ImageAttributes attrib = new ImageAttributes();
attrib.SetColorKey(KeyColor, KeyColor);
g.DrawImage(gradientImage, rc, 0, 0,
gradientImage.Width, gradientImage.Height,
GraphicsUnit.Pixel, attrib);
// Clean up
gxTemp.Dispose();
tempImage.Dispose();
gxGradient.Dispose();
gradientImage.Dispose();
}
}
}
図形に対してのグラデーションの適用
まず例として最初に円形のグラデーションの描画をします。
Windows Mobileでは、
(1)ベースになるグラデーションイメージを用意する
赤から黒への単純なグラデーションイメージを用意しました。このグラデーションイメージが、

(2)グラデーションをクリッピングするイメージを作る
背景をマゼンタで塗り潰し、

透過させる色に緑色を設定して、

マゼンタを背景としたグラデーション掛かった円形のイメージの完成です。

(3)円形のグラデーションを描画する
次に透過色をマゼンタに設定して、

様々な図形のグラデーションを描画するための準備
前記のDrawGradientEllipseメソッドの処理では円形にしか対応していません。今後簡単に図形を足して行けるようにGraphicsExtensionクラスを書き換えてみました。
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
namespace GradientionSample
{
public class GraphicsExtension
{
// 透過用のキーカラー
public static Color KeyColor = Color.FromArgb(255, 0, 255);
// クリッピング用画像描画デリゲート定義
private delegate void InnderDrawFunction(Graphics g,
Rectangle rc, Color fillColor, Color borderColor);
// グラデーション描画メソッド(共通処理)
private static void InnerDrawGradient(Graphics g, Rectangle rc,
Color startColor, Color endColor, Color borderColor,
FillDirection gradientType, InnderDrawFunction func)
{
// クリッピング用の色の設定
Color clippingColor = Color.Green;
Rectangle rect = new Rectangle(0, 0, rc.Width, rc.Height);
// グラデーションを描画するイメージの生成
Bitmap gradientImage = new Bitmap(rc.Width, rc.Height,
PixelFormat.Format16bppRgb565);
Graphics gxGradient = Graphics.FromImage(gradientImage);
// グラデーションを描画する
GradientFill.Fill(gxGradient, rect,
startColor, endColor, FillDirection.TopToBottom);
// 任意の図形でグラデーションを切り抜く為のイメージの生成
Bitmap tempImage = new Bitmap(rc.Width, rc.Height,
PixelFormat.Format16bppRgb565);
// クリッピング用の図形を描画するdelegateを呼ぶ
Graphics gxTemp = Graphics.FromImage(tempImage);
func(gxTemp, rect, clippingColor, borderColor);
// グラデーションイメージに対して、
// クリッピング用のイメージを、緑色の透過色を使用して上書きする
ImageAttributes clippingAttr = new ImageAttributes();
clippingAttr.SetColorKey(clippingColor, clippingColor);
gxGradient.DrawImage(tempImage,
rect, 0, 0, rect.Width, rect.Height,
GraphicsUnit.Pixel, clippingAttr);
// グラデーションの掛かった図形を描画する
ImageAttributes attrib = new ImageAttributes();
attrib.SetColorKey(KeyColor, KeyColor);
g.DrawImage(gradientImage, rc, 0, 0,
gradientImage.Width, gradientImage.Height,
GraphicsUnit.Pixel, attrib);
// Clean up
gxTemp.Dispose();
tempImage.Dispose();
gxGradient.Dispose();
gradientImage.Dispose();
}
// グラデーションが掛かった円形を描画する
public static void DrawGradientEllipse(
Graphics g, Rectangle rc,
Color startColor, Color endColor, Color borderColor,
FillDirection gradientType)
{
InnerDrawGradient(g, rc, startColor,
endColor, borderColor, gradientType,
new InnderDrawFunction(_DrawEllipse));
}
// クリッピング用の図形を描画するメソッド
private static void _DrawEllipse(Graphics g,
Rectangle rc, Color fillColor, Color borderColor)
{
// 描画用オブジェクトの取得
SolidBrush fillBrush = new SolidBrush(fillColor);
Pen borderPen = new Pen(borderColor);
// 背景は透過色でクリアしておく
g.Clear(KeyColor);
// 円を描く
g.FillEllipse(fillBrush, rc);
// ボーダーを描画する
if (borderColor != Color.Empty)
{
g.DrawEllipse(borderPen, rc);
}
// 描画用オブジェクトの解放
fillBrush.Dispose();
fillBrush = null;
borderPen.Dispose();
borderPen = null;
}
}
}
publicにするDrawXXXメソッドと、
グラデーションの掛かった星形を描画する
描画用メソッドとクリッピング用の図形を描画するメソッドを用意します。下記のメソッドをGraphicsExtensionクラスに追加してください。
// グラデーションが掛かった円形を描画する
public static void DrawGradientStar(
Graphics g, Rectangle rc,
Color startColor, Color endColor, Color borderColor,
FillDirection gradientType)
{
InnerDrawGradient(g, rc, startColor,
endColor, borderColor, gradientType,
new InnderDrawFunction(_DrawStar));
}
// クリッピング用の図形を描画するメソッド
private static void _DrawStar(Graphics g,
Rectangle rc, Color fillColor, Color borderColor)
{
// 描画用オブジェクトの取得
SolidBrush fillBrush = new SolidBrush(fillColor);
Pen borderPen = new Pen(borderColor);
// 背景は透過色でクリアしておく
g.Clear(KeyColor);
// 星形を描画する
Point[] apt = new Point[5];
for (int i = 0; i < apt.Length; i++)
{
double dAngle = (i * 0.8 - 0.5) * Math.PI;
apt[i] = new Point(
(int)(rc.Width * (0.50 + 0.48 * Math.Cos(dAngle))),
(int)(rc.Height * (0.50 + 0.48 * Math.Sin(dAngle))));
}
g.FillPolygon(fillBrush, apt);
// ボーダーを描画する
if (borderColor != Color.Empty)
{
g.DrawPolygon(borderPen, apt);
}
// 描画用オブジェクトの解放
fillBrush.Dispose();
fillBrush = null;
borderPen.Dispose();
borderPen = null;
}
呼び出し元のForm.
protected override void OnPaint(PaintEventArgs e)
{
// グラデーションを描画する図形を設定する
Rectangle rect = new Rectangle();
rect.Width = this.Width / 2;
rect.Height = this.Height / 2;
rect.X = (this.Width - rect.Width) / 2;
rect.Y = (this.Height - rect.Height) / 2;
// グラデーション開始色
Color startColor = Color.Red;
// グラデーション終了色
Color endColor = Color.Black;
// グラデーションの方向
FillDirection type = FillDirection.TopToBottom;
// グラデーションの掛かった星形を描く
GraphicsExtension.DrawGradientStar(e.Graphics,
rect, startColor, endColor, Color.Empty, type);
}
実行の結果、

さいごに
サンプルコードを実行しながら、
次回は、
以上で今回は終わりです。ありがとうございました。