0

I'm trying to find the best way to draw polygons in C# with edges that gradually blend into the background color. I'm drawing the polygons to a bitmap, so currently I'm using the Graphics classes from System.Drawing.

The polygons will be a blend mask, I have no problem to draw the polgons black and white. But I want them to gradually transition between the two colors over a certain amount of pixels, let's say 50 pixels (that size should be specified).

I came across the PathGradiantBrush but I couldn't find a way to specify the size of the transition zone. With that brush the transition seems to depend on the size and shape of the polygon and not be fixed size.

What's the best way to draw such polygons?

TaW
  • 53,122
  • 8
  • 69
  • 111

2 Answers2

1

As you can see in the other answer, gradient brushes do fill a path or polygon with a centered gradient; you can set the center point but they will still not really follow the polygon's edges:

enter image description here

You can influence the relative width of each color band by creating a ColorBlend going to Transparent and suitable Positions, as I did for the above result, but the angle of the egdes towards the center point and their distance from the bounding rectangle will still determine their absolute widths. For a muliticolor gradient brush example see here!


So, unless your polygon is nearly circular you need to do it differently.

Here is a solution, which will follow the edges:

enter image description here

Using a GraphicsPath path (or simply a Point array) and a Graphics object g it first fills in the background color and then draws the path with pens that both grow in width and in transparency. To keep the outer edges both in place and opaque I set the Pen.Alignment = PenAlignment.Inset. You can play with the numbers, of course..:

g.FillPath(Brushes.MediumSeaGreen, path);

int ew = 8; // edge width

for (int i = 0; i < ew ; i++)
    using (Pen pen = new Pen(Color.FromArgb(255 - i * 255 / ew, Color.DarkSlateBlue), i ))
    {
        pen.Alignment = PenAlignment.Inset;
        g.DrawPath(pen, path);
    }

Note that the left edge looks a little thicker but it really isn't; just an optical illusion..

Community
  • 1
  • 1
TaW
  • 53,122
  • 8
  • 69
  • 111
  • Thanks, this approach to draw different lines at the edge of the shape would work for what I want to do. I'm going to give that a try. – Arno Gerretsen Sep 28 '16 at 18:06
0

I looked at the Path Gradient Brush on MSDN and found out about the FocusScales property which I believe attempts to solve problem you're faced with.

Here is an example from this page showing the use of FocusScales:

// Create a path that consists of a single ellipse.
GraphicsPath path;
path.AddEllipse(0, 0, 200, 100);

// Create a path gradient brush based on the elliptical path.
PathGradientBrush pthGrBrush(&path);
pthGrBrush.SetGammaCorrection(TRUE);

// Set the color along the entire boundary to blue.
Color color(Color(255, 0, 0, 255));
INT num = 1;
pthGrBrush.SetSurroundColors(&color, &num);

// Set the center color to aqua.
pthGrBrush.SetCenterColor(Color(255, 0, 255, 255));

// Use the path gradient brush to fill the ellipse. 
graphics.FillPath(&pthGrBrush, &path);

// Set the focus scales for the path gradient brush.
pthGrBrush.SetFocusScales(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.
graphics.TranslateTransform(220.0f, 0.0f);
graphics.FillPath(&pthGrBrush, &path);

And an example of the output:

Example of FocusScales