Parthi
Parthi

Reputation: 391

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

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.

   https://i.sstatic.net/B4CHB.png

But I get the result like this

  https://i.sstatic.net/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

Upvotes: 0

Views: 2150

Answers (2)

TaW
TaW

Reputation: 54433

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):

enter image description hereenter image description here

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..

Upvotes: 1

lc.
lc.

Reputation: 116528

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

Upvotes: 1

Related Questions