11

I'd like to create image (from another one) with rounded corners with GDI+. What's the best way to do this?

PS: it's not for web, so I cannot make use of client CSS

cocoapriest
  • 1,869
  • 3
  • 22
  • 36

6 Answers6

25

This function seems to do what you want. It can also easily be modified to return a Bitmap if needed. You'll also need to clean up any images you no longer want, etc.. Adapted from: http://www.jigar.net/howdoi/viewhtmlcontent98.aspx

using System.Drawing;
using System.Drawing.Drawing2D;

public Image RoundCorners(Image StartImage, int CornerRadius, Color BackgroundColor)
{
    CornerRadius *= 2;
    Bitmap RoundedImage = new Bitmap(StartImage.Width, StartImage.Height);
    using(Graphics g = Graphics.FromImage(RoundedImage))
    {
      g.Clear(BackgroundColor);
      g.SmoothingMode = SmoothingMode.AntiAlias;
      Brush brush = new TextureBrush(StartImage);
      GraphicsPath gp = new GraphicsPath();
      gp.AddArc(0, 0, CornerRadius, CornerRadius, 180, 90);
      gp.AddArc(0 + RoundedImage.Width - CornerRadius, 0, CornerRadius, CornerRadius, 270, 90);
      gp.AddArc(0 + RoundedImage.Width - CornerRadius, 0 + RoundedImage.Height - CornerRadius, CornerRadius, CornerRadius, 0, 90);
      gp.AddArc(0, 0 + RoundedImage.Height - CornerRadius, CornerRadius, CornerRadius, 90, 90);
      g.FillPath(brush, gp);
      return RoundedImage;
    }
}

Image StartImage = Image.FromFile("YourImageFile.jpg");
Image RoundedImage = this.RoundCorners(StartImage, 25, Color.White);
//Use RoundedImage...
Reza
  • 18,865
  • 13
  • 88
  • 163
Gary Willoughby
  • 50,926
  • 41
  • 133
  • 199
  • is there a way to smoothen the edges even further. compare #5 & #6 in this image http://danbystrom.files.wordpress.com/2008/08/fluffysample.jpg – Vaibhav Garg May 06 '10 at 13:24
  • 1
    Maybe try changing the smoothing mode in the method to `SmoothingMode.HighQuality` ? – Gary Willoughby May 06 '10 at 19:22
  • Thank you. I was able to modify this to write a method that will crop an image into a circle: https://stackoverflow.com/a/57223769/1202807 – Gabriel Luci Jul 26 '19 at 16:21
9

Using the Graphics.SetClip() method is the best way. For example:

    public static Image OvalImage(Image img) {
        Bitmap bmp = new Bitmap(img.Width, img.Height);
        using (GraphicsPath gp = new GraphicsPath()) {
            gp.AddEllipse(0, 0, img.Width, img.Height);
            using (Graphics gr = Graphics.FromImage(bmp)) {
                gr.SetClip(gp);
                gr.DrawImage(img, Point.Empty);
            }
        }
        return bmp;
    }
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 1
    This literally creates an image in the shape of an oval or circle. Good to know how this can be done, but not what people typically mean by "rounded corners". No adjustment of the corner radius using this method. – jk7 Jan 20 '17 at 20:38
  • 4
    Come on, use your imagination for pete sake. You can make any shape you want with a GraphicsPath by combining arcs, lines, polygons and beziers. – Hans Passant Jan 20 '17 at 21:14
5

The most straightforward way would be to use a scalable mask with rounded corners. Apply the mask to the image and export the new image.

Here is a CodeProject article dealing with precisely that.

Dave Swersky
  • 34,502
  • 9
  • 78
  • 118
5

I ended up combining both https://stackoverflow.com/a/1759073 and https://stackoverflow.com/a/1759225 to get my rounded images, as I wanted the background to be transparent. Thought I'd share it:

private Image RoundCorners(Image image, int cornerRadius)
{
    cornerRadius *= 2;
    Bitmap roundedImage = new Bitmap(image.Width, image.Height);
    GraphicsPath gp = new GraphicsPath();
    gp.AddArc(0, 0, cornerRadius, cornerRadius, 180, 90);
    gp.AddArc(0 + roundedImage.Width - cornerRadius, 0, cornerRadius, cornerRadius, 270, 90);
    gp.AddArc(0 + roundedImage.Width - cornerRadius, 0 + roundedImage.Height - cornerRadius, cornerRadius, cornerRadius, 0, 90);
    gp.AddArc(0, 0 + roundedImage.Height - cornerRadius, cornerRadius, cornerRadius, 90, 90);
    using (Graphics g = Graphics.FromImage(roundedImage))
    {
        g.SmoothingMode = SmoothingMode.HighQuality;
        g.SetClip(gp);
        g.DrawImage(image, Point.Empty);
    }
    return roundedImage;
}
Community
  • 1
  • 1
MagicMau
  • 305
  • 3
  • 10
2

All the other answers suffer from a problem with a 1 pixel distortion along the left and top border. This code fixes the problem by offsetting -1 pixels in the left and top when adding the arcs for the mask.

public static Image RoundCorners(Image StartImage, int CornerRadius, Color BackgroundColor)
{
    CornerRadius *= 2;
    Bitmap RoundedImage = new Bitmap(StartImage.Width, StartImage.Height);

    using(Graphics g = Graphics.FromImage(RoundedImage))
    {
       g.Clear(BackgroundColor);
       g.SmoothingMode = SmoothingMode.HighQuality;
       g.CompositingQuality = CompositingQuality.HighQuality;
       g.InterpolationMode = InterpolationMode.HighQualityBicubic;

       using(Brush brush = new TextureBrush(StartImage))
       {
          using(GraphicsPath gp = new GraphicsPath())
          {
             gp.AddArc(-1, -1, CornerRadius, CornerRadius, 180, 90);
             gp.AddArc(0 + RoundedImage.Width - CornerRadius, -1, CornerRadius, CornerRadius, 270, 90);
             gp.AddArc(0 + RoundedImage.Width - CornerRadius, 0 + RoundedImage.Height - CornerRadius, CornerRadius, CornerRadius, 0, 90);
             gp.AddArc(-1, 0 + RoundedImage.Height - CornerRadius, CornerRadius, CornerRadius, 90, 90);

             g.FillPath(brush, gp);
          }
       }

       return RoundedImage;
    }
}
jjxtra
  • 20,415
  • 16
  • 100
  • 140
0

Smoother edges when circling.

public static Image RoundCorners(Image StartImage, float CornerRadius, Color BackgroundColor)
{
    CornerRadius *= 2;
    Bitmap RoundedImage = new Bitmap(StartImage.Width, StartImage.Height);

    using(Graphics g = Graphics.FromImage(RoundedImage))
    {
       g.Clear(BackgroundColor);
       g.SmoothingMode = SmoothingMode.HighQuality;
       g.CompositingQuality = CompositingQuality.HighQuality;
       g.InterpolationMode = InterpolationMode.HighQualityBicubic;

       using(Brush brush = new TextureBrush(StartImage))
       {
          using(GraphicsPath gp = new GraphicsPath())
          {
            gp.AddArc(0, -1, CornerRadius, CornerRadius, 180, 90);
            gp.AddArc(-1 + RoundedImage.Width - CornerRadius, -1, CornerRadius, CornerRadius, 270, 90);
            gp.AddArc(-1 + RoundedImage.Width - CornerRadius, -1 + RoundedImage.Height - CornerRadius, CornerRadius, CornerRadius, 0, 90);
            gp.AddArc(0, -1 + RoundedImage.Height - CornerRadius, CornerRadius, CornerRadius, 90, 90);

             g.FillPath(brush, gp);
          }
       }

       return RoundedImage;
    }
}
Emre
  • 97
  • 8