使用渐变画笔填充形状

      可借助渐变画笔用渐变的颜色填充形状。例如,可借助水平渐变画笔,从形状的左边缘到右边缘用逐渐变化的颜色来填充形状。设想这样一个矩形:它的左边缘为黑色(红色、绿色和蓝色分量均为 0);右边为红色(这三个分量分别为 255,0,0)。如果矩形的宽度为 256 个像素,则给定像素的红色分量将多于其左侧的像素的红色分量。在一行中,最左边像素的颜色分量为 (0, 0, 0);第二个像素的分量为 (1, 0, 0);第三个为 (2, 0, 0),依此类推,直到到达最右边的像素,它的分量为 (255, 0, 0)。这些插值颜色的值构成了颜色渐变。

当水平地、垂直地或平行一指定的斜线移动到时,线性渐变改变颜色。当在轨迹的内部和边界来回移动时,轨迹渐变改变颜色。可自定义轨迹渐变以获得多种效果。

下面的插图显示用线性渐变画笔填充矩形,用路径渐变画笔填充椭圆。

渐变

 

 

一。如何:创建线性渐变

GDI+ 提供水平、垂直和对角线方向线性渐变。在默认情况下,线性渐变中的颜色均匀地变化。当然,也可自定义线性渐变,使颜色非均匀变化。

下面的示例使用水平线性渐变画笔填充线条、椭圆和矩形。

LinearGradientBrush 构造函数接收四个参数:两个点和两种颜色。第一个点 (0, 10) 与第一种颜色(红色)相关联,第二个点 (200, 10) 与第二种颜色(蓝色)相关联。正如您所期望的那样,从 (0, 10) 绘制到 (200, 10) 的线条的颜色从红色逐渐变成蓝色。

点 (50, 10) 和点 (200, 10) 中的 10 无关紧要。重要的是这两个点的第二个坐标相同——它们之间的连线是水平的。当水平坐标从 0 移到 200 时,椭圆和矩形也逐渐从红色变成蓝色。

下面的插图显示线条、椭圆和矩形。请注意,当水平坐标增加到 200 以上时,颜色渐变重复其自身。

线性渐变

使用水平线性渐变

  • 将不透明红和不透明蓝分别作为第三和第四个参数传递。

LinearGradientBrush linGrBrush = new LinearGradientBrush(
   new Point(0, 10),
   new Point(200, 10),
   Color.FromArgb(255, 255, 0, 0),   // Opaque red
   Color.FromArgb(255, 0, 0, 255));  // Opaque blue

Pen pen = new Pen(linGrBrush);

e.Graphics.DrawLine(pen, 0, 10, 200, 10);
e.Graphics.FillEllipse(linGrBrush, 0, 30, 200, 100);
e.Graphics.FillRectangle(linGrBrush, 0, 155, 500, 30);

在上面的示例中,当您从水平坐标 0 移到水平坐标 200 时,颜色分量成线性变化。例如,如果某个点的第一个坐标位于 0 和 200 的正中间,则其蓝色分量将是 0 和 255 正中间的值。

GDI+ 允许调整颜色从渐变的一个边缘到另一个边缘变化的方式。假设您希望按照下表创建从黑色变到红色的渐变画笔。

水平坐标 RGB 分量

0

(0, 0, 0)

40

(128, 0, 0)

200

(255, 0, 0)

请注意,当水平坐标才达到 0 到 200 之间的 20% 时,红色分量已达到一半亮度。

下面的示例设置 LinearGradientBrush 对象的 Blend 属性,以便使三个相对亮度与三个相对位置相关联。正如上表所示,相对亮度 0.5 与相对位置 0.2 相关联。该代码用渐变画笔填充椭圆和矩形。

下面的插图显示所得到的椭圆和矩形。

线性渐变

自定义线性渐变

  • 将不透明黑和不透明红分别作为第三和第四个参数传递。

 

LinearGradientBrush linGrBrush = new LinearGradientBrush(
   new Point(0, 10),
   new Point(200, 10),
   Color.FromArgb(255, 0, 0, 0),     // Opaque black 
   Color.FromArgb(255, 255, 0, 0));  // Opaque red

float[] relativeIntensities = { 0.0f, 0.5f, 1.0f };
float[] relativePositions = { 0.0f, 0.2f, 1.0f };

//Create a Blend object and assign it to linGrBrush.
Blend blend = new Blend();
blend.Factors = relativeIntensities;
blend.Positions = relativePositions;
linGrBrush.Blend = blend;

e.Graphics.FillEllipse(linGrBrush, 0, 30, 200, 100);
e.Graphics.FillRectangle(linGrBrush, 0, 155, 500, 30);

在上面的示例中,渐变的方向是水平的;即,当沿着水平线移动时,颜色逐渐变化。还可以定义垂直渐变和对角线渐变。

下面的示例将点 (0, 0) 和点 (200, 100) 传递给 LinearGradientBrush 构造函数。蓝色与 (0, 0) 相关联,绿色与 (200, 100) 相关联。用线性渐变画笔填充线条(画笔的宽度为 10)和椭圆。

下面的插图显示该线条和椭圆。请注意,当沿着任何与穿过 (0, 0) 和 (200, 100) 的直线平行的直线移动时,椭圆中的颜色逐渐变化。

线性渐变

创建对角线性渐变

  • 将不透明蓝和不透明绿分别作为第三和第四个参数传递。

LinearGradientBrush linGrBrush = new LinearGradientBrush(
   new Point(0, 0),
   new Point(200, 100),
   Color.FromArgb(255, 0, 0, 255),   // opaque blue
   Color.FromArgb(255, 0, 255, 0));  // opaque green

Pen pen = new Pen(linGrBrush, 10);

e.Graphics.DrawLine(pen, 0, 0, 600, 300);
e.Graphics.FillEllipse(linGrBrush, 10, 100, 200, 100);

 

请参见

其他资源

二。如何:创建路径渐变

PathGradientBrush 类使您可以自定义用渐变色填充形状的方式。例如,可为轨迹的中心指定一种颜色;为轨迹的边界指定另一种颜色。还可为轨迹边界上的七个点分别指定颜色。

Note注意

在 GDI+ 中,路径是由 GraphicsPath 对象维护的一系列线条和曲线。有关 GDI+ 路径的更多信息,请参见GDI+ 中的图形路径构造并绘制轨迹

使用路径渐变填充椭圆

  • 下面的示例用路径渐变画笔填充椭圆。中心的颜色设置为蓝色;边界的颜色设置为浅绿色。下面的插图显示已填充的椭圆。

渐变路径

默认情况下,路径渐变画笔不会延伸到路径边界以外。如果您使用路径渐变画笔来填充延伸到路径边界以外的图形,则无法填充路径以外的屏幕区域。

渐变路径
// 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);

在边界上指定点

  • 下面的示例由星形轨迹构造路径渐变画笔。该代码设置 CenterColor 属性,它将星形中心的颜色设置为红色。然后,该代码设置 SurroundColors 属性,以便在 points 数组中的各个点处指定不同的颜色(存储在 colors 数组中)。最后一个代码语句用路径渐变画笔填充星形轨迹。

// 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);
  • 下面的示例在代码中不使用 GraphicsPath 对象而绘制一个路径渐变。在该示例中,特定的 PathGradientBrush 构造函数接收一系列点,但是不需要 GraphicsPath 对象。同时,请注意,PathGradientBrush 用于填充矩形而不是填充路径。矩形比用于定义画笔的闭合轨迹大,因此矩形的某些部分未由画笔涂色。下面的插图显示该矩形(虚线)以及该矩形被路径渐变画笔涂色的那部分。

  • 渐变

     

    // 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));

    自定义路径渐变

    • 自定义路径渐变画笔的一种方法就是设置它的 FocusScales 属性。聚焦缩放指定位于主轨迹内部的内部轨迹。中心颜色显示在内部轨迹中的任何地方,而不是只显示在中心点。

      下面的示例根据椭圆轨迹创建路径渐变画笔。该代码将边界颜色设置为蓝色,将中心颜色设置为浅绿色,然后使用路径渐变画笔填充椭圆轨迹。

      接着,该代码设置路径渐变画笔的聚焦缩放。x 聚焦缩放被设置为 0.3,y 聚焦缩放被设置为 0.8。该代码调用 Graphics 对象的 TranslateTransform 方法,以便后来对 FillPath 的调用填充位于第一个椭圆右侧的椭圆。

      若要观看聚焦缩放的效果,请设想一个与主椭圆共用一个中心的小椭圆。小(内部)椭圆是由主椭圆在水平方向上缩小 0.3 倍,在垂直方向上缩小 0.8 倍(围绕其中心)得到的。当从外部椭圆的边界移到内部椭圆的边界时,颜色逐渐从蓝色变成浅绿色。当从内部椭圆的边界移到共用中心时,颜色保持浅绿色。

      下面的插图显示以下代码的输出。左边的椭圆只在中心点上为浅绿色。右边的椭圆在内部轨迹内部的任何地方都为浅绿色。

    渐变
    // 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);

    使用插值自定义

    • 自定义路径渐变画笔的另一种方法是指定插值颜色数组和插值位置数组。

      下面的示例基于三角形创建路径渐变画笔。该代码设置路径渐变画笔的 InterpolationColors 属性,以便指定插值颜色数组(深绿色,浅绿色,蓝色)和插值位置数组 (0, 0.25, 1)。当从三角形的边界移到中心点时,颜色将从深绿色逐渐变成浅绿色,然后从浅绿色变成蓝色。深绿色到浅绿色的转变发生在深绿色到蓝色转变的距离的 25% 处。

      下面的插图显示用自定义路径渐变画笔填充的三角形。

      渐变路径

     

    // 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);

    设置中心点

    • 在默认情况下,路径渐变画笔的中心点位于用来构造梯度刷的轨迹的形心。可通过设置 PathGradientBrush 类的 CenterPoint 属性更改中心点的位置。

      下面的示例基于椭圆来创建路径渐变画笔。椭圆的中心位于 (70, 35),但是路径渐变画笔的中心点设置在 (120, 40)。

     

    // 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);
    

    下面的插图显示实心椭圆和路径渐变画笔的中心点。

    渐变路径

    • 可将路径渐变画笔的中心点设置在用于构造梯度刷的轨迹外部的某个位置。下面的示例通过替换调用来设置以上代码中的 CenterPoint 属性。

     

    pthGrBrush.CenterPoint = new PointF(145, 35);

    下面的插图显示更改后的输出。

    渐变路径

    在上面的插图中,椭圆最右边的那些点不是纯蓝色(尽管它们非常接近)。渐变中颜色的定位就好像是填充到颜色为纯蓝色 (0, 0, 255) 的点 (145, 35)。但是,由于路径渐变画笔只在其轨迹内部涂色,所以并未填充到点 (145, 35)。

    请参见

    三。如何:对渐变应用灰度校正

    可通过将渐变画笔的 GammaCorrection 属性设置为 true 来启用线性渐变画笔的伽玛矫正。可通过将 GammaCorrection 属性设置为 false 来禁用伽玛矫正。在默认情况下,禁用伽玛矫正。

    示例

    下面的示例创建一个线性渐变画笔并使用它填充两个矩形。第一个矩形在填充时未启用伽玛矫正;第二个矩形在填充时启用了伽玛矫正。

    下面的插图显示这两个实心矩形。上面的矩形未采用伽玛矫正,它的中间部分看上去较暗。下面的矩形采用了伽玛矫正,看上去亮度更均匀。

    渐变

    编译代码

    前面的示例是为使用 Windows 窗体而设计的,它需要 Paint 事件处理程序的参数 PaintEventArgs e

    请参见

    
    
    posted @ 2009-09-29 14:09  张兴业  阅读(698)  评论(0编辑  收藏  举报