パス グラデーションを作成する

PathGradientBrush クラスを使用すると、徐々に変化する色で図形を塗りつぶす方法をカスタマイズできます。 PathGradientBrush オブジェクトには、境界パスと中心点があります。 中心点に 1 つの色を指定し、境界に別の色を指定できます。 境界に沿って複数のポイントごとに個別の色を指定することもできます。

Note

GDI+ では、パスは GraphicsPath オブジェクトによって維持される線と曲線のシーケンスです。 GDI+ パスの詳細については、Paths および Constructing and Drawing Paths を参照してください。

 

次の例では、パス グラデーション ブラシを使用して楕円を塗りつぶします。 中心の色は青に設定され、境界の色はアクアに設定されます。

// Create a path that consists of a single ellipse.
GraphicsPath path;
path.AddEllipse(0, 0, 140, 70);

// Use the path to construct a brush.
PathGradientBrush pthGrBrush(&path);

// Set the color at the center of the path to blue.
pthGrBrush.SetCenterColor(Color(255, 0, 0, 255));

// Set the color along the entire boundary of the path to aqua.
Color colors[] = {Color(255, 0, 255, 255)};
int count = 1;
pthGrBrush.SetSurroundColors(colors, &count);

graphics.FillEllipse(&pthGrBrush, 0, 0, 140, 70);

次の図に、塗りつぶされた楕円を示します。

グラデーションで塗りつぶされた楕円を示すイラスト

既定では、パス グラデーション ブラシはパスの境界の外側には拡張されません。 パス グラデーション ブラシを使用して、パスの境界を越えて広がる図形を塗りつぶした場合、パスの外側の画面領域は塗りつぶされません。 次の図は、前のコードの Graphics::FillEllipse 呼び出しを graphics.FillRectangle(&pthGrBrush, 0, 10, 200, 40)に変更した場合の動作を示しています。

前の楕円の水平スライスを示す図

境界上のポイントの指定

次の使用例は、星形のパスからパス グラデーション ブラシを作成します。 このコードは PathGradientBrush::SetCenterColor メソッドを呼び出して、星の重心の色を赤に設定します。 次に、PathGradientBrush::SetSurroundColors メソッドを呼び出して、ポイント配列内の個々のポイントでさまざまな色 (colors 配列に格納) を指定します。 最後のコード文では、星形のパスをパス グラデーション ブラシで塗りつぶします。

// Put the points of a polygon in an array.
Point points[] = {Point(75, 0),    Point(100, 50), 
                  Point(150, 50),  Point(112, 75),
                  Point(150, 150), Point(75, 100), 
                  Point(0, 150),   Point(37, 75), 
                  Point(0, 50),    Point(50, 50)};

// Use the array of points to construct a path.
GraphicsPath path;
path.AddLines(points, 10);

// Use the path to construct a path gradient brush.
PathGradientBrush pthGrBrush(&path);

// Set the color at the center of the path to red.
pthGrBrush.SetCenterColor(Color(255, 255, 0, 0));

// Set the colors of the points in the array.
Color colors[] = {Color(255, 0, 0, 0),   Color(255, 0, 255, 0),
                  Color(255, 0, 0, 255), Color(255, 255, 255, 255), 
                  Color(255, 0, 0, 0),   Color(255, 0, 255, 0), 
                  Color(255, 0, 0, 255), Color(255, 255, 255, 255),
                  Color(255, 0, 0, 0),   Color(255, 0, 255, 0)};

int count = 10;
pthGrBrush.SetSurroundColors(colors, &count);

// Fill the path with the path gradient brush.
graphics.FillPath(&pthGrBrush, &path);

次の図に、塗りつぶされたスターを示します。

中心が赤で、星の各先端に向かってさまざまな色にグラデーションしていく五芒星を描いたイラスト

次の使用例は、ポイントの配列に基づいてパス グラデーション ブラシを作成します。 配列内の 5 つの各ポイントに色が割り当てられます。 5 つのポイントを直線で接続すると、5 辺の多角形が得られます。 色は、その多角形の中心 (重心) にも割り当てられます。この例では、中心 (80,75) が白に設定されています。 この例の最後のコード文では、パス グラデーション ブラシを使用して四角形を塗りつぶします。

四角形の塗りつぶしに使用される色は (80, 75) で白で、(80, 75) から配列内のポイントに向かって移動すると徐々に変化します。 たとえば、(80, 75) から (0, 0) に移動すると、色は白から赤に徐々に変化し、(80, 75) から (160, 0) に移動すると、色は白から緑に徐々に変化します。

// Construct a path gradient brush based on an array of points.
PointF ptsF[] = {PointF(0.0f, 0.0f), 
                 PointF(160.0f, 0.0f), 
                 PointF(160.0f, 200.0f),
                 PointF(80.0f, 150.0f),
                 PointF(0.0f, 200.0f)};

PathGradientBrush pBrush(ptsF, 5);

// An array of five points was used to construct the path gradient
// brush. Set the color of each point in that array.
Color colors[] = {Color(255, 255, 0, 0),  // (0, 0) red
                  Color(255, 0, 255, 0),  // (160, 0) green
                  Color(255, 0, 255, 0),  // (160, 200) green
                  Color(255, 0, 0, 255),  // (80, 150) blue
                  Color(255, 255, 0, 0)}; // (0, 200) red

int count = 5;
pBrush.SetSurroundColors(colors, &count);

// Set the center color to white.
pBrush.SetCenterColor(Color(255, 255, 255, 255));

// Use the path gradient brush to fill a rectangle.
graphics.FillRectangle(&pBrush, Rect(0, 0, 180, 220));

上記のコードには GraphicsPath オブジェクトがないことに注意してください。 この例の特定 の PathGradientBrush コンストラクターは、ポイントの配列へのポインターを受け取りますが、 GraphicsPath オブジェクトは必要ありません。 また、パス グラデーション ブラシは、パスではなく四角形を塗りつぶすために使用されることに注意してください。 四角形はブラシの定義に使用されるパスよりも大きいので、一部の四角形はブラシによって描画されません。 次の図は、四角形 (点線) と、パス グラデーション ブラシによって塗りつぶされた四角形の部分を示しています。

複数色のグラデーションで部分的に塗りつぶされた点線で囲まれた四角形を示す図

パス グラデーションのカスタマイズ

パス グラデーション ブラシをカスタマイズする 1 つの方法は、フォーカス スケールを設定する方法です。 フォーカス スケールは、メイン パス内にある内部パスを指定します。 中心の色は、中心点だけでなく、その内側のパス内のすべての場所に表示されます。 パス グラデーション ブラシのフォーカス スケールを設定するには、 PathGradientBrush::SetFocusScales メソッドを 呼び出します。

次の使用例は、楕円パスに基づいてパス グラデーション ブラシを作成します。 このコードでは、境界の色を青に設定し、中心の色を aqua に設定した後、パス グラデーション ブラシを使用して楕円パスを塗りつぶします。

次に、パス グラデーション ブラシのフォーカス スケールを設定します。 x フォーカス スケールは 0.3 に設定され、y フォーカス スケールは 0.8 に設定されます。 このコードは Graphics オブジェクトの Graphics::TranslateTransform メソッドを呼び出し、以降の Graphics::FillPath の呼び出しで最初の楕円の右側にある楕円が塗りつぶされるようにします。

フォーカス スケールの効果を確認するには、中心を主楕円と共有する小さな楕円を想像してください。 小さい (内側) 楕円は、水平方向に 0.3 倍、垂直方向に 0.8 倍にスケーリングされた主楕円です。 外側の楕円の境界から内側の楕円の境界に移動すると、色は青からアクアに徐々に変化します。 内側の楕円の境界から共有の中心に移動すると、色はアクアのままです。

// Create a path that consists of a single ellipse.
GraphicsPath path;
path.AddEllipse(0, 0, 200, 100);

// Create a path gradient brush based on the elliptical path.
PathGradientBrush pthGrBrush(&path);
pthGrBrush.SetGammaCorrection(TRUE);

// Set the color along the entire boundary to blue.
Color color(Color(255, 0, 0, 255));
INT num = 1;
pthGrBrush.SetSurroundColors(&color, &num);

// Set the center color to aqua.
pthGrBrush.SetCenterColor(Color(255, 0, 255, 255));
 
// Use the path gradient brush to fill the ellipse. 
graphics.FillPath(&pthGrBrush, &path);

// Set the focus scales for the path gradient brush.
pthGrBrush.SetFocusScales(0.3f, 0.8f);

// Use the path gradient brush to fill the ellipse again.
// Show this filled ellipse to the right of the first filled ellipse.
graphics.TranslateTransform(220.0f, 0.0f);
graphics.FillPath(&pthGrBrush, &path);

次の図は、上記のコードの出力を示しています。 左側の楕円は、中心点でのみアクアです。 右側の楕円は、内側のパスの内側全体がアクア色です。

アクア色から青へとグラデーションした2つの楕円を示した図: 1つ目はアクア色の部分がほとんどなく、2つ目ははるかに多い

パス グラデーション ブラシをカスタマイズするもう 1 つの方法は、プリセットカラーの配列と補間位置の配列を指定することです。

次の使用例は、三角形に基づいてパス グラデーション ブラシを作成します。 このコードでは、パス グラデーション ブラシの PathGradientBrush::SetInterpolationColors メソッドを呼び出して、補間色の配列 (濃い緑、アクア、青) と補間位置の配列 (0, 0.25, 1) を指定します。 三角形の境界から中心点に移動すると、色は濃い緑からアクアに、次に水色から青に徐々に変化します。 濃い緑からアクアへの変化は、濃い緑から青までの距離の 25% で発生します。

// Vertices of the triangle
Point points[] = {Point(100, 0), 
                  Point(200, 200), 
                  Point(0, 200)};

// No GraphicsPath object is created. The PathGradient
// brush is constructed directly from the array of points.
PathGradientBrush pthGrBrush(points, 3);

Color presetColors[] = {
   Color(255, 0, 128, 0),    // Dark green
   Color(255, 0, 255, 255),  // Aqua
   Color(255, 0, 0, 255)};   // Blue

REAL interpPositions[] = {
   0.0f,   // Dark green is at the boundary of the triangle.
   0.25f,  // Aqua is 25 percent of the way from the boundary
           // to the center point.
   1.0f};  // Blue is at the center point.
                  
pthGrBrush.SetInterpolationColors(presetColors, interpPositions, 3);

// Fill a rectangle that is larger than the triangle
// specified in the Point array. The portion of the
// rectangle outside the triangle will not be painted.
graphics.FillRectangle(&pthGrBrush, 0, 0, 200, 200);

次の図は、上記のコードの出力を示しています。

中央が青で、水色を経て、端に向かって緑になる三角形を示す図

中心点の設定

既定では、パス グラデーション ブラシの中心点は、そのブラシの作成に使用されるパスの重心に位置します。 中心点の位置を変更するには、PathGradientBrush クラスの PathGradientBrush::SetCenterPoint メソッドを呼び出します。

次の使用例は、楕円に基づいてパス グラデーション ブラシを作成します。 楕円の中心は (70, 35) ですが、パス グラデーション ブラシの中心点は (120, 40) に設定されます。

// Create a path that consists of a single ellipse.
GraphicsPath path;
path.AddEllipse(0, 0, 140, 70);

// Use the path to construct a brush.
PathGradientBrush pthGrBrush(&path);

// Set the center point to a location that is not the centroid of the path.
pthGrBrush.SetCenterPoint(Point(120, 40));

// Set the color at the center point to blue.
pthGrBrush.SetCenterColor(Color(255, 0, 0, 255));

// Set the color along the entire boundary of the path to aqua.
Color colors[] = {Color(255, 0, 255, 255)};
int count = 1;
pthGrBrush.SetSurroundColors(colors, &count);

graphics.FillEllipse(&pthGrBrush, 0, 0, 140, 70);

次の図は、塗りつぶされた楕円とパス グラデーション ブラシの中心点を示しています。

一方の端付近の中心点から青から水色に塗りつぶされる楕円を示す図

パス グラデーション ブラシの中心点を、ブラシの構築に使用されたパスの外側の位置に設定できます。 前のコードでは、 PathGradientBrush::SetCenterPoint の呼び出しを pthGrBrush.SetCenterPoint(Point(145, 35)) に置き換えた場合、次の結果が得られます。

楕円の端の外側にある中心点から青から水色に塗りつぶされる楕円を示す図

上の図では、楕円の右端の点は純粋な青ではありません (ただし、非常に近いです)。 グラデーション内の色は、塗りつぶしが点 (145, 35) に達するまで許されていたとした場合、色が純粋な青 (0, 0, 255) になっていたかのように配置されています。 ただし、パス グラデーション ブラシではパスの内側のみが描画されるため、塗りつぶしが (145, 35) まで達することはありません。

パスグラデーションの色の計算方法

パス内の各ピクセルに対して、ブラシは中心点からそのピクセルを通り、光線がパスの境界と交わる点まで仮想的な光線を伸ばします。 そのピクセルの色は、そのレイに沿ったピクセルの位置に基づいて、中心の色と境界の色の間で線形補間されます。 具体的には、補間係数は、中心点からピクセルまでの距離の比率であり、中心点から境界交差までの合計距離で割った値です。

中心点がパスの外側にある場合、中心点に最も近いパスの側のピクセルは短い光線を持ちます (境界がその方向に近いため)。 これらのピクセルは短い光線に沿って比較的遠いので、中心の色に近いように見えます。 パスの反対側のピクセルは長い光線を持ち、境界の色に近い場所に表示されます。 これは、前の図では、外部中心点の近くの境界に、アクア (境界の色) ではなく青に近い色 (中心の色) が表示される理由を説明しています。