自定义类 PathGradientBrush 使您能够根据逐渐变化的颜色来定制填充形状的方式。 例如,可以为路径的中心指定一种颜色,并为路径的边界指定另一种颜色。 还可以为路径边界上的多个点中的每一个指定单独的颜色。
注释
在 GDI+ 中,路径是由 GraphicsPath 对象维护的线条和曲线序列。 有关 GDI+ 路径的详细信息,请参阅 GDI+ 中的图形路径以及构造和绘图路径。
本文中的示例是从控件的 Paint 事件处理程序调用的方法。
使用路径渐变来填充椭圆
以下示例使用路径渐变画笔填充椭圆。 中心颜色设置为蓝色,边界颜色设置为水绿色。 下图显示了填充的椭圆。
默认情况下,路径渐变画笔不会扩展到路径边界之外。 如果使用路径渐变画笔填充超出路径边界的图形,那么路径之外的区域将不会被填充。
以下插图显示了将以下代码中的Graphics.FillEllipse调用更改为
e.Graphics.FillRectangle(pthGrBrush, 0, 10, 200, 40)
后会发生什么:public void FillEllipseWithPathGradient(PaintEventArgs e) { // Create a path that consists of a single ellipse. GraphicsPath path = new GraphicsPath(); path.AddEllipse(0, 0, 140, 70); // Use the path to construct a brush. PathGradientBrush pthGrBrush = new PathGradientBrush(path); // Set the color at the center of the path to blue. pthGrBrush.CenterColor = Color.FromArgb(255, 0, 0, 255); // Set the color along the entire boundary // of the path to aqua. Color[] colors = { Color.FromArgb(255, 0, 255, 255) }; pthGrBrush.SurroundColors = colors; e.Graphics.FillEllipse(pthGrBrush, 0, 0, 140, 70); }
' Create a path that consists of a single ellipse. Dim path As New GraphicsPath() path.AddEllipse(0, 0, 140, 70) ' Use the path to construct a brush. Dim pthGrBrush As New PathGradientBrush(path) ' Set the color at the center of the path to blue. pthGrBrush.CenterColor = Color.FromArgb(255, 0, 0, 255) ' Set the color along the entire boundary ' of the path to aqua. Dim colors As Color() = {Color.FromArgb(255, 0, 255, 255)} pthGrBrush.SurroundColors = colors e.Graphics.FillEllipse(pthGrBrush, 0, 0, 140, 70)
前面的代码示例是为 Windows 窗体设计的,它要求 PaintEventArgs 参数 e,这是 PaintEventHandler 的一个参数。
指定边界上的点
以下示例创建一个从星形图案路径构建的路径渐变画笔。 代码设置 CenterColor 属性,该属性将星心处的颜色设置为红色。 然后,代码设置 SurroundColors 属性,以在
points
数组中的各个点指定各种颜色(这些颜色存储在colors
数组中)。 最后一个代码语句使用路径渐变画笔填充星形路径。public void ConstructBrushFromStarShapedPath(PaintEventArgs e) { // Put the points of a polygon in an array. Point[] points = { new Point(75, 0), new Point(100, 50), new Point(150, 50), new Point(112, 75), new Point(150, 150), new Point(75, 100), new Point(0, 150), new Point(37, 75), new Point(0, 50), new Point(50, 50)}; // Use the array of points to construct a path. GraphicsPath path = new GraphicsPath(); path.AddLines(points); // Use the path to construct a path gradient brush. PathGradientBrush pthGrBrush = new PathGradientBrush(path); // Set the color at the center of the path to red. pthGrBrush.CenterColor = Color.FromArgb(255, 255, 0, 0); // Set the colors of the points in the array. Color[] colors = { Color.FromArgb(255, 0, 0, 0), Color.FromArgb(255, 0, 255, 0), Color.FromArgb(255, 0, 0, 255), Color.FromArgb(255, 255, 255, 255), Color.FromArgb(255, 0, 0, 0), Color.FromArgb(255, 0, 255, 0), Color.FromArgb(255, 0, 0, 255), Color.FromArgb(255, 255, 255, 255), Color.FromArgb(255, 0, 0, 0), Color.FromArgb(255, 0, 255, 0)}; pthGrBrush.SurroundColors = colors; // Fill the path with the path gradient brush. e.Graphics.FillPath(pthGrBrush, path); }
' Put the points of a polygon in an array. Dim points As Point() = { _ New Point(75, 0), _ New Point(100, 50), _ New Point(150, 50), _ New Point(112, 75), _ New Point(150, 150), _ New Point(75, 100), _ New Point(0, 150), _ New Point(37, 75), _ New Point(0, 50), _ New Point(50, 50)} ' Use the array of points to construct a path. Dim path As New GraphicsPath() path.AddLines(points) ' Use the path to construct a path gradient brush. Dim pthGrBrush As New PathGradientBrush(path) ' Set the color at the center of the path to red. pthGrBrush.CenterColor = Color.FromArgb(255, 255, 0, 0) ' Set the colors of the points in the array. Dim colors As Color() = { _ Color.FromArgb(255, 0, 0, 0), _ Color.FromArgb(255, 0, 255, 0), _ Color.FromArgb(255, 0, 0, 255), _ Color.FromArgb(255, 255, 255, 255), _ Color.FromArgb(255, 0, 0, 0), _ Color.FromArgb(255, 0, 255, 0), _ Color.FromArgb(255, 0, 0, 255), _ Color.FromArgb(255, 255, 255, 255), _ Color.FromArgb(255, 0, 0, 0), _ Color.FromArgb(255, 0, 255, 0)} pthGrBrush.SurroundColors = colors ' Fill the path with the path gradient brush. e.Graphics.FillPath(pthGrBrush, path)
以下示例在代码中绘制路径渐变,而无需 GraphicsPath 对象。 示例中的特定 PathGradientBrush 构造函数接收点数组,但不需要对象 GraphicsPath 。 此外,请注意,PathGradientBrush 用于填充矩形,而不是路径。 矩形大于用于定义画笔的封闭路径,因此画笔未能涂绘矩形的某些部分。 下图显示了矩形(虚线)和路径渐变画笔绘制的矩形部分:
public void DrawPathGradentWthoutGraphicsPath(PaintEventArgs e) { // Construct a path gradient brush based on an array of points. PointF[] ptsF = { new PointF(0, 0), new PointF(160, 0), new PointF(160, 200), new PointF(80, 150), new PointF(0, 200)}; PathGradientBrush pBrush = new PathGradientBrush(ptsF); // 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.FromArgb(255, 255, 0, 0), // (0, 0) red Color.FromArgb(255, 0, 255, 0), // (160, 0) green Color.FromArgb(255, 0, 255, 0), // (160, 200) green Color.FromArgb(255, 0, 0, 255), // (80, 150) blue Color.FromArgb(255, 255, 0, 0)}; // (0, 200) red pBrush.SurroundColors = colors; // Set the center color to white. pBrush.CenterColor = Color.White; // Use the path gradient brush to fill a rectangle. e.Graphics.FillRectangle(pBrush, new Rectangle(0, 0, 160, 200)); }
' Construct a path gradient brush based on an array of points. Dim ptsF As PointF() = { _ New PointF(0, 0), _ New PointF(160, 0), _ New PointF(160, 200), _ New PointF(80, 150), _ New PointF(0, 200)} Dim pBrush As New PathGradientBrush(ptsF) ' An array of five points was used to construct the path gradient ' brush. Set the color of each point in that array. 'Point (0, 0) is red 'Point (160, 0) is green 'Point (160, 200) is green 'Point (80, 150) is blue 'Point (0, 200) is red Dim colors As Color() = { _ Color.FromArgb(255, 255, 0, 0), _ Color.FromArgb(255, 0, 255, 0), _ Color.FromArgb(255, 0, 255, 0), _ Color.FromArgb(255, 0, 0, 255), _ Color.FromArgb(255, 255, 0, 0)} pBrush.SurroundColors = colors ' Set the center color to white. pBrush.CenterColor = Color.White ' Use the path gradient brush to fill a rectangle. e.Graphics.FillRectangle(pBrush, New Rectangle(0, 0, 160, 200))
自定义路径渐变
自定义路径渐变画笔的一种方法是设置其 FocusScales 属性。 焦点缩放指定位于主路径内部的内部路径。 中心颜色显示在该内部路径内的任意位置,而不是仅在中心点显示。
以下示例基于椭圆路径创建路径渐变画笔。 代码将边界颜色设置为蓝色,将中心颜色设置为水蓝色,然后使用路径渐变画笔来填充椭圆路径。
接下来,代码设置路径渐变画笔的焦点刻度。 x 焦点规模设置为 0.3,y 焦点规模设置为 0.8。 代码调用 Graphics 对象的 TranslateTransform 方法,以便后续调用 FillPath 时填充一个位于第一个椭圆右侧的椭圆。
若要查看焦点缩放的效果,想象一个小椭圆,它与主椭圆共享其中心。 小椭圆(内椭圆)是将主要椭圆水平缩放 0.3 倍,并垂直缩放 0.8 倍(以其中心为基准)。 当你从外部椭圆的边界移动到内椭圆的边界时,颜色逐渐从蓝色变为水绿色。 当你从内椭圆的边界移动到共享中心时,颜色将保持水绿色。
下图显示了以下代码的输出。 左侧的椭圆只有在中心点是浅蓝色。 右侧的椭圆在内部路径内的区域都是水绿色的。
public void CustomizePathGradientBrush(PaintEventArgs e)
{
// Create a path that consists of a single ellipse.
GraphicsPath path = new GraphicsPath();
path.AddEllipse(0, 0, 200, 100);
// Create a path gradient brush based on the elliptical path.
PathGradientBrush pthGrBrush = new PathGradientBrush(path);
// Set the color along the entire boundary to blue.
Color[] color = { Color.Blue };
pthGrBrush.SurroundColors = color;
// Set the center color to aqua.
pthGrBrush.CenterColor = Color.Aqua;
// Use the path gradient brush to fill the ellipse.
e.Graphics.FillPath(pthGrBrush, path);
// Set the focus scales for the path gradient brush.
pthGrBrush.FocusScales = new PointF(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.
e.Graphics.TranslateTransform(220.0f, 0.0f);
e.Graphics.FillPath(pthGrBrush, path);
}
' Create a path that consists of a single ellipse.
Dim path As New GraphicsPath()
path.AddEllipse(0, 0, 200, 100)
' Create a path gradient brush based on the elliptical path.
Dim pthGrBrush As New PathGradientBrush(path)
' Set the color along the entire boundary to blue.
' Changed variable name from color
Dim blueColor As Color() = {Color.Blue}
pthGrBrush.SurroundColors = blueColor
' Set the center color to aqua.
pthGrBrush.CenterColor = Color.Aqua
' Use the path gradient brush to fill the ellipse.
e.Graphics.FillPath(pthGrBrush, path)
' Set the focus scales for the path gradient brush.
pthGrBrush.FocusScales = New PointF(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.
e.Graphics.TranslateTransform(220.0F, 0.0F)
e.Graphics.FillPath(pthGrBrush, path)
使用插值自定义
自定义路径渐变画笔的另一种方法是指定内插颜色数组和内插位置数组。
以下示例展示了如何基于一个三角形来创建路径渐变笔刷。 代码设置 InterpolationColors 路径渐变画笔的属性,以指定内插颜色数组(深绿色、水、蓝色)和内插位置数组(0,0.25,1)。 当你从三角形的边界移动到中心点时,颜色逐渐从深绿色变为水绿色,然后从水绿色变为蓝色。 从深绿色到水的改变发生在从深绿色到蓝色的距离的25%中。
下图显示了用自定义路径渐变画笔填充的三角形。
public void CustomizeWithInterpolation(PaintEventArgs e) { // Vertices of the outer triangle Point[] points = { new Point(100, 0), new Point(200, 200), new Point(0, 200)}; // No GraphicsPath object is created. The PathGradientBrush // object is constructed directly from the array of points. PathGradientBrush pthGrBrush = new PathGradientBrush(points); Color[] colors = { Color.FromArgb(255, 0, 128, 0), // dark green Color.FromArgb(255, 0, 255, 255), // aqua Color.FromArgb(255, 0, 0, 255)}; // blue float[] relativePositions = { 0f, // Dark green is at the boundary of the triangle. 0.4f, // Aqua is 40 percent of the way from the boundary // to the center point. 1.0f}; // Blue is at the center point. ColorBlend colorBlend = new ColorBlend(); colorBlend.Colors = colors; colorBlend.Positions = relativePositions; pthGrBrush.InterpolationColors = colorBlend; // 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. e.Graphics.FillRectangle(pthGrBrush, 0, 0, 200, 200); }
' Vertices of the outer triangle Dim points As Point() = { _ New Point(100, 0), _ New Point(200, 200), _ New Point(0, 200)} ' No GraphicsPath object is created. The PathGradientBrush ' object is constructed directly from the array of points. Dim pthGrBrush As New PathGradientBrush(points) ' Create an array of colors containing dark green, aqua, and blue. Dim colors As Color() = { _ Color.FromArgb(255, 0, 128, 0), _ Color.FromArgb(255, 0, 255, 255), _ Color.FromArgb(255, 0, 0, 255)} ' Dark green is at the boundary of the triangle. ' Aqua is 40 percent of the way from the boundary to the center point. ' Blue is at the center point. Dim relativePositions As Single() = { _ 0.0F, _ 0.4F, _ 1.0F} Dim colorBlend As New ColorBlend() colorBlend.Colors = colors colorBlend.Positions = relativePositions pthGrBrush.InterpolationColors = colorBlend ' 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. e.Graphics.FillRectangle(pthGrBrush, 0, 0, 200, 200)
设置中心点
默认情况下,路径渐变画笔的中心点位于用于构造画笔的路径的质心处。 可以通过设置 CenterPoint 类的属性 PathGradientBrush 来更改中心点的位置。
以下示例展示了如何基于椭圆创建路径渐变画笔。 椭圆的中心位于(70,35),但路径渐变画笔的中心点设置为(120,40)。
public void SetCenterPoint(PaintEventArgs e) { // Create a path that consists of a single ellipse. GraphicsPath path = new GraphicsPath(); path.AddEllipse(0, 0, 140, 70); // Use the path to construct a brush. PathGradientBrush pthGrBrush = new PathGradientBrush(path); // Set the center point to a ___location that is not // the centroid of the path. pthGrBrush.CenterPoint = new PointF(120, 40); // Set the color at the center of the path to blue. pthGrBrush.CenterColor = Color.FromArgb(255, 0, 0, 255); // Set the color along the entire boundary // of the path to aqua. Color[] colors = { Color.FromArgb(255, 0, 255, 255) }; pthGrBrush.SurroundColors = colors; e.Graphics.FillEllipse(pthGrBrush, 0, 0, 140, 70); }
' Create a path that consists of a single ellipse. Dim path As New GraphicsPath() path.AddEllipse(0, 0, 140, 70) ' Use the path to construct a brush. Dim pthGrBrush As New PathGradientBrush(path) ' Set the center point to a ___location that is not ' the centroid of the path. pthGrBrush.CenterPoint = New PointF(120, 40) ' Set the color at the center of the path to blue. pthGrBrush.CenterColor = Color.FromArgb(255, 0, 0, 255) ' Set the color along the entire boundary ' of the path to aqua. Dim colors As Color() = {Color.FromArgb(255, 0, 255, 255)} pthGrBrush.SurroundColors = colors e.Graphics.FillEllipse(pthGrBrush, 0, 0, 140, 70)
下图显示了路径渐变画笔的填充椭圆和中心点:
可以将路径渐变画笔的中心点设置为用于构造画笔的路径外部的位置。 以下示例替换调用以设置 CenterPoint 上述代码中的属性。
public void SetCenterPointOutsidePath(PaintEventArgs e) { // Create a path that consists of a single ellipse. GraphicsPath path = new GraphicsPath(); path.AddEllipse(0, 0, 140, 70); // Use the path to construct a brush. PathGradientBrush pthGrBrush = new PathGradientBrush(path); // Set the center point to a ___location that is not // the centroid of the path. pthGrBrush.CenterPoint = new PointF(145, 35); // Set the color at the center of the path to blue. pthGrBrush.CenterColor = Color.FromArgb(255, 0, 0, 255); // Set the color along the entire boundary // of the path to aqua. Color[] colors = { Color.FromArgb(255, 0, 255, 255) }; pthGrBrush.SurroundColors = colors; e.Graphics.FillEllipse(pthGrBrush, 0, 0, 140, 70); }
pthGrBrush.CenterPoint = New PointF(145, 35)
下图显示了此更改的输出:
在上图中,椭圆最右侧的点不是纯蓝色(尽管它们非常接近)。 渐变中的颜色定位为填充到达点(145,35),其中颜色为纯蓝色(0,0,0,255)。 但是填充永远不会达到(145,35),因为路径渐变画笔只在其路径内绘制。
编译代码
前面的示例旨在与 Windows 窗体一起使用,并且它们需要 PaintEventArgse
,这是事件处理程序的参数 Paint 。