How to draw a rounded rectangle in c#
Asked Answered
E

2

37

I am using this code to make a rounded rectangle, but it only draws upper left and right corners of rectangle, more it doesn't not complete the rectangle at lower part. How do I make it complete and filled. What changes should I make?

public static Bitmap DrawRoundedRectangle(Bitmap Image, Color BoxColor, int XPosition, int YPosition,
        int Height, int Width, int CornerRadius)

{
    Bitmap NewBitmap = new Bitmap(Image, Image.Width, Image.Height);
    using (Graphics NewGraphics = Graphics.FromImage(NewBitmap))
    {
        using (Pen BoxPen = new Pen(BoxColor))
        {
            using (GraphicsPath Path = new GraphicsPath())
            {
                Path.AddLine(XPosition + CornerRadius, YPosition, XPosition + Width - (CornerRadius * 2), YPosition);
                Path.AddArc(XPosition + Width - (CornerRadius * 2), YPosition, CornerRadius * 2, CornerRadius * 2, 270, 90);
                Path.AddLine(XPosition + Width, YPosition + CornerRadius, XPosition + Width, YPosition + Height - (CornerRadius * 2));
                Path.AddArc(XPosition + Width - (CornerRadius * 2), YPosition + Height - (CornerRadius * 2), CornerRadius * 2, CornerRadius * 2, 0, 90);
                Path.AddLine(XPosition + Width - (CornerRadius * 2), YPosition + Height, XPosition + CornerRadius, YPosition + Height);
                Path.AddArc(XPosition, YPosition + Height - (CornerRadius * 2), CornerRadius * 2, CornerRadius * 2, 90, 90);
                Path.AddLine(XPosition, YPosition + Height - (CornerRadius * 2), XPosition, YPosition + CornerRadius);
                Path.AddArc(XPosition, YPosition, CornerRadius * 2, CornerRadius * 2, 180, 90);

                Path.CloseFigure();
                NewGraphics.DrawPath(BoxPen, Path);
           }
       }
   }
   return NewBitmap;
}
Equalitarian answered 22/11, 2015 at 9:40 Comment(0)
D
83
public static GraphicsPath RoundedRect(Rectangle bounds, int radius)
{
    int diameter = radius * 2;
    Size size = new Size(diameter, diameter);
    Rectangle arc = new Rectangle(bounds.Location, size);
    GraphicsPath path = new GraphicsPath();

    if (radius == 0)
    {
        path.AddRectangle(bounds);
        return path;
    }

    // top left arc  
    path.AddArc(arc, 180, 90);

    // top right arc  
    arc.X = bounds.Right - diameter;
    path.AddArc(arc, 270, 90);

    // bottom right arc  
    arc.Y = bounds.Bottom - diameter;
    path.AddArc(arc, 0, 90);

    // bottom left arc 
    arc.X = bounds.Left;
    path.AddArc(arc, 90, 90);

    path.CloseFigure();
    return path;
}

And you can make two extension methods for the Graphics type so you can use them as the usual Draw... and Fill... shape-drawing methods.

public static void DrawRoundedRectangle(this Graphics graphics, Pen pen, Rectangle bounds, int cornerRadius)
{
    if (graphics == null)
        throw new ArgumentNullException(nameof(graphics));
    if (pen == null)
        throw new ArgumentNullException(nameof(pen));

    using (GraphicsPath path = RoundedRect(bounds, cornerRadius))
    {
        graphics.DrawPath(pen, path);
    }
}

public static void FillRoundedRectangle(this Graphics graphics, Brush brush, Rectangle bounds, int cornerRadius)
{
    if (graphics == null)
        throw new ArgumentNullException(nameof(graphics));
    if (brush == null)
        throw new ArgumentNullException(nameof(brush));

    using(GraphicsPath path = RoundedRect(bounds, cornerRadius))
    {
        graphics.FillPath(brush, path);
    }
}

Update 2020:

Recently I made my drawing libraries publicly available (NuGet). Feel free to explore the GraphicsExtensions class for more overloads (custom corner radius for each corners), and for other goodies.

Ducal answered 22/11, 2015 at 9:57 Comment(3)
Kőszeghow , can I draw control shadow using your library?Binding
@Realbitt: The library is not bound to any specific control library. Do you mean WinForms controls? Dropping a shadow for a control is tricky because the shadow exceeds the control boundaries so you should paint it on the parent control. But in general, to drop shadow you need a Bitmap source rather than a GraphicsPath. A rounded borderless Form is a special case though: set Form.Region from the GraphicsPath and override CreateParams to make the form drop a shadow.Would
yes, I finally realized that, and I succeed to write code in containers base class to drop shadow for their Childs by bool property, and that's more enough for me. Thanks GyorgyBinding
A
8

I have modified György Kőszeg's answer for those who wants different corners.

public static GraphicsPath RoundedRect(Rectangle bounds, int radius1, int radius2, int radius3, int radius4)
    {
        int diameter1 = radius1 * 2;
        int diameter2 = radius2 * 2;
        int diameter3 = radius3 * 2;
        int diameter4 = radius4 * 2;

        Rectangle arc1 = new Rectangle(bounds.Location, new Size(diameter1, diameter1));
        Rectangle arc2 = new Rectangle(bounds.Location, new Size(diameter2, diameter2));
        Rectangle arc3 = new Rectangle(bounds.Location, new Size(diameter3, diameter3));
        Rectangle arc4 = new Rectangle(bounds.Location, new Size(diameter4, diameter4));
        GraphicsPath path = new GraphicsPath();

        // top left arc  
        if (radius1 == 0)
        {
            path.AddLine(arc1.Location, arc1.Location);
        }
        else
        {
            path.AddArc(arc1, 180, 90);
        }

        // top right arc  
        arc2.X = bounds.Right - diameter2;
        if (radius2 == 0)
        {
            path.AddLine(arc2.Location, arc2.Location);
        }
        else
        {
            path.AddArc(arc2, 270, 90);
        }

        // bottom right arc  

        arc3.X = bounds.Right - diameter3;
        arc3.Y = bounds.Bottom - diameter3;
        if (radius3 == 0)
        {
            path.AddLine(arc3.Location, arc3.Location);
        }
        else
        {
            path.AddArc(arc3, 0, 90);
        }

        // bottom left arc 
        arc4.X = bounds.Right - diameter4;
        arc4.Y = bounds.Bottom - diameter4;
        arc4.X = bounds.Left;
        if (radius4 == 0)
        {
            path.AddLine(arc4.Location, arc4.Location);
        }
        else
        {
            path.AddArc(arc4, 90, 90);
        }

        path.CloseFigure();
        return path;
    }
Acclivity answered 14/5, 2021 at 5:21 Comment(1)
This version was already linked in the updated answer a year before this answer. ;) Nice effort anyway. I was just too lazy to include the customized corners version...Would

© 2022 - 2025 — McMap. All rights reserved.