Reputation: 923
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;
}
Upvotes: 37
Views: 45905
Reputation: 18043
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.
Upvotes: 83
Reputation: 188
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;
}
Upvotes: 9