Search code examples
c#polygongradientsystem.drawing

polygon with blended edges


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?


Solution

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