Ian Vink
Ian Vink

Reputation: 68770

MonoTouch: Rounded UIImage Convenience Method

Is there a MonoTouch built-in method to round the edges of a UIImage ?

I seem to remember seeing it once.

Upvotes: 2

Views: 2255

Answers (5)

cvsguimaraes
cvsguimaraes

Reputation: 13240

Based on BahaiResearch.com answer I've made another method for non-square images and a roundness percentage instead of a literal radius.

I'm not sure if it will produce ellipsis correctly. So I'll appreciate if some one can test or even improve this method.

private static UIImage RoundCorners (UIImage image, float roundnessPercentage)
{
    float width = image.Size.Width;
    float height = image.Size.Height;
    float radius = ((width+height)/2) * (roundnessPercentage/(100*2));

    UIGraphics.BeginImageContext (new SizeF (width, height));
    CGContext c = UIGraphics.GetCurrentContext();

    c.BeginPath ();
    c.MoveTo(width, height/2);
    //Bottom-right Corner
    c.AddArcToPoint(width, height, height / 2, width, radius);
    //Bottom-left Corner
    c.AddArcToPoint(0, height, 0, 0, radius);
    //Top-left Corner
    c.AddArcToPoint(0, 0, width/2, 0, radius);
    //Top-right Corner
    c.AddArcToPoint(width, 0, width, height/2, radius);
    c.ClosePath();
    c.Clip();

    image.Draw (new PointF (0, 0));
    UIImage converted = UIGraphics.GetImageFromCurrentImageContext();
    UIGraphics.EndImageContext ();
    return converted;
}

Upvotes: 0

Ian Vink
Ian Vink

Reputation: 68770

Here is a nice code helper for MonoTouch users looking for a quick helper function. Tweeked code came from the Excellent Xamarin.com site:

public static UIImage RounderCorners (UIImage image, float width, float radius)
{
    UIGraphics.BeginImageContext (new SizeF (width, width));
    var c = UIGraphics.GetCurrentContext ();

                //Note: You need to write the Device.IsRetina code yourself 
    radius = Device.IsRetina ? radius * 2 : radius;

    c.BeginPath ();
    c.MoveTo (width, width / 2);
    c.AddArcToPoint (width, width, width / 2, width, radius);
    c.AddArcToPoint (0, width, 0, width / 2, radius);
    c.AddArcToPoint (0, 0, width / 2, 0, radius);
    c.AddArcToPoint (width, 0, width, width / 2, radius);
    c.ClosePath ();
    c.Clip ();

    image.Draw (new PointF (0, 0));
    var converted = UIGraphics.GetImageFromCurrentImageContext ();
    UIGraphics.EndImageContext ();
    return converted;
}

Upvotes: 3

miguel.de.icaza
miguel.de.icaza

Reputation: 32694

Rounding a UIImage would produce another UIImage.

You can do this if you create a CGContext to render into with the same size as the original image, then add a clipping path with the rounded corners and rendering your original UIImage.

Then you can pull the UIImage out of the CGContext.

Another option is to avoid the intermediate step, is to push the graphics state in your context drawing, add the rounded path as a clipping path, draw the image and then pop the graphics state to go back to this.

You can see how TweetStation uses this for its Glass Buttons:

https://github.com/migueldeicaza/MonoTouch.Dialog/blob/master/MonoTouch.Dialog/Utilities/GlassButton.cs#L76

Upvotes: 3

Lorenzo B
Lorenzo B

Reputation: 33428

I also suggest you the following tutorial on introduction-to-calayers-tutorial. It covers interesting stuffs on customizing layers in iOS.

Hope it helps.

Upvotes: 1

poupou
poupou

Reputation: 43553

In MonoTouch (and iOS itself) it's not something you can do on UIImage itself. However you can do this on UIImageView by manipulating its Layer property.

See this answer for an Objective-C example that would be simple to convert to C#.

Upvotes: 2

Related Questions