Drawing a Box With Rounded Corners in C#

I've talked quite a bit about different algorithms for manipulating images in various ways. Everything from convolution filters to contrast manipulation to even some procedural image generation such as perlin noise. However through all of that, I never really covered drawing your own images. Sure perlin noise is a form of drawing, I guess, but what if all you need is a box drawn around something? Are we out of luck, having to draw that pixel by pixel?

The quick answer is no, within the GDI framework there are a set of classes within the System.Drawing and System.Drawing.Drawing2D that allows us to draw various objects by calling their functions. For instance within the Graphics class we can draw arcs, rectangles, lines, etc. Each function is well documented and easy to use (just remember that 0,0 is the upper left hand corner of an image). However other than circles, arcs, lines, etc. there really isn't anything complex that it can draw for us. For instance there is no way to tell it that we want rounded corners. So for items like that we have to cobble the object together from what we're given. So lets look at how we would draw a box with rounded corners.

        /// <summary>
        /// Draws a rounded rectangle on a bitmap
        /// </summary>
        /// <param name="Image">Image to draw on</param>
        /// <param name="BoxColor">The color that the box should be</param>
        /// <param name="XPosition">The upper right corner's x position</param>
        /// <param name="YPosition">The upper right corner's y position</param>
        /// <param name="Height">Height of the box</param>
        /// <param name="Width">Width of the box</param>
        /// <param name="CornerRadius">Radius of the corners</param>
        /// <returns>The bitmap with the rounded box on it</returns>
        public static Bitmap DrawRoundedRectangle(Bitmap Image, Color BoxColor, int XPosition, int YPosition,
            int Height, int Width, int CornerRadius)
        {
            System.Drawing.Bitmap TempBitmap = Image;
            System.Drawing.Bitmap NewBitmap = new System.Drawing.Bitmap(TempBitmap, TempBitmap.Width, TempBitmap.Height);
            System.Drawing.Graphics NewGraphics = System.Drawing.Graphics.FromImage(NewBitmap);

            Pen BoxPen = new Pen(BoxColor);
            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);
            NewGraphics.Dispose();
            return NewBitmap;
        }

The code above takes in a number of variables including the height, width, upper left hand corner position of the box, and the radius of the corners. The function then creates a Pen as well as a Path object. The Pen object defines what color and thickness the lines will be when we draw them. The Path object actually draws the box. It does this by drawing a line for each side and an arc at each corner. Once the box is drawn, it closes the figure, and tell the Graphics object to actually draw it on the image (note that doing this allows you to create one path and reuse it on multiple images, so you're not recreating it each time). That's all there is to it. So take a look at the Path class, leave feedback, and happy coding.

kick it on DotNetKicks.com   Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkListEmail

Posted by: James Craig
Posted on: 5/5/2009 at 9:07 AM
Tags: , ,
Categories: C#
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading