Search code examples
c#winformsgraphicsdrawingrectangles

How to draw a rounded rectangle in c#


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

Solution

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