0

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.stack.imgur.com/B4CHB.png

But I get the result like this

  https://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

Parthi
  • 361
  • 6
  • 21
  • Each time I read the question I understand less. Can you post an image of what you want?. Also: `Region` is a class in `GDI+`, closely related to `GraphicsPath`. I see no `Region` in your code. If you mean just some area please don't call it `Region`! – TaW Mar 13 '15 at 08:14
  • Region is general word to represent the area, so i can use it here. If you have answer for this question, please share with me. – Parthi Mar 13 '15 at 08:48
  • `Region` is a reserved word in `.Net/GDI+` and using it here will only create confusion. I probably could answer your problem if I would understand it. If Lc's answer is not enough, please do consider uploading an image! – TaW Mar 13 '15 at 09:09
  • please now find my problem and please provide your valuable idea to overcome the problem. – Parthi Mar 13 '15 at 09:36
  • Thanks for the images. Now I see what you mean. (An image often is better than a thousand words) Have a look at two examples.. – TaW Mar 13 '15 at 23:25

2 Answers2

1

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);
}
lc.
  • 113,939
  • 20
  • 158
  • 187
  • Thanks for you help. I have a circle path and linear brush, now I want to fill the circle path using linear gradient brush bounds and remaining area from the circle path filled with another color. Is it possible to do in GDI+? – Parthi Mar 13 '15 at 06:36
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):

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

TaW
  • 53,122
  • 8
  • 69
  • 111