How to fill the linear gradient brush region from the original region?

巧了我就是萌 提交于 2019-12-10 11:57:00

问题


I’m using LinearGradient brush to fill the region and I created the linearGradient brush using starting and ending points, Color.

  Rectangle linearGradientregion= new Rectangl(20,-50,30,30);
  LinearGradientBrush linearGradientBrush = new LinearGradientBrush(new PointF(20, -20), new PointF(50, -50), Color.Green, Color.Red);


  Rectangle pathRegion= new Rectangl(-50,-25,50,50);
  GraphicsPath path = new GraphicsPath();
  path.AddRectangle(pathRegion);
  graphics.FillPath(linearGradientBrush, path);

And the region size is greater than linearGradientBrush bounds area.

Now I want to know how to fill the region using linearGradientBrush bounds area only using linearGradientBrush and remaining area from the region filled with another color.

Below image is expect output.

   http://i.stack.imgur.com/B4CHB.png

But I get the result like this

  http://i.stack.imgur.com/Pxwiw.png

In first image the circle filled with green color is beyond the bounds of linear gradient brush.

In second image the gradient brush again comes to fill that region.

I want to stop the gradient brush fill at end point of linear gradient brush and fill the remaining area with another color.

Thanks in advance,

Parthi


回答1:


There are several ways to accomplish this task:

  • You could do it in two steps, first filling the circle and then filling a triangle with the circle set as the ClippingPath (Graphics.SetClip(path)) of the Graphics object.

  • You could do it in two steps, first rotating the Graphics object by your angle, then filling the circle and then filling a Rectangle, again with the circle set as the ClippingPath of the Graphics object. Finally rotate back.

  • Or you can do it in one step: Create a multicolored LinearGradientBrush, and set the positions so that the green area starts with next to no transition.

Here are two solutions using the third method (left image) and the second one (right image):

Solution one using the third method with a multicolored gradient:

private void panel1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.Clear(Color.White);
    e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
    Rectangle linearGradientregion = new Rectangle(10, 10, 150, 150);
    Rectangle pathRegion = new Rectangle(15, 15, 140, 140);
    GraphicsPath path = new GraphicsPath();
    path.AddEllipse(pathRegion);
    LinearGradientBrush linearGradientBrush = 
       new LinearGradientBrush(linearGradientregion, Color.Red, Color.Yellow, 45);

    ColorBlend cblend = new ColorBlend(4);
    cblend.Colors = new Color[4]  { Color.Red, Color.Yellow, Color.Green, Color.Green };
    cblend.Positions = new float[4] { 0f, 0.65f, 0.65f, 1f };

    linearGradientBrush.InterpolationColors = cblend;

    e.Graphics.FillPath(linearGradientBrush, path);
}

Note that I didn't use your coordinate setup.. I'm sure you can adapt the numbers.

Also note that the Colors from the constructor are not used by the Brush!

Solution two using the second method. Note the sharp transition to green:

private void panel3_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.Clear(Color.White);
    e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
    Rectangle linearGradientregion = new Rectangle(10, 10, 95, 95);
    Rectangle pathRegion = new Rectangle(15, 15, 140, 140);
    int centerX = pathRegion.X + pathRegion.Width / 2;
    int centerY = pathRegion.Y + pathRegion.Height / 2;

    GraphicsPath path = new GraphicsPath();
    path.AddEllipse(pathRegion);
    LinearGradientBrush linearGradientBrush = 
        new LinearGradientBrush(linearGradientregion, Color.Red, Color.Yellow, 45);
    e.Graphics.FillPath(linearGradientBrush, path);
    e.Graphics.SetClip(path);

    e.Graphics.TranslateTransform(centerX, centerY);
    e.Graphics.RotateTransform(45f);
    e.Graphics.FillRectangle(Brushes.Green, 25, -90, 240, 240);
    e.Graphics.ResetTransform();
}

Again it is up to you to figure out the best numbers..




回答2:


To fill the gradient, you have to specify the exact area to fill. in your case I believe this is linearGradientregion:

graphics.FillRectangle(linearGradientBrush, linearGradientregion);

To fill the remaining area, use a GraphicsPath in alternate fill mode (the default). Add the two rectangles to the path, then the outer shape will be filled and the inner shape outside the clipping region and thus left alone. For example:

using(var externalPath = new GraphicsPath(FillMode.Alternate))
{
    externalPath.AddRectangle(pathRegion);
    externalPath.AddRectangle(linearGradientregion);

    graphics.FillPath(Brushes.Black, externalPath);
}


来源:https://stackoverflow.com/questions/29025026/how-to-fill-the-linear-gradient-brush-region-from-the-original-region

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!