views:

3363

answers:

6

How to mask a square image into an image with round corners?

A: 

Create an image with opaque rounded corners and a transparent middle region in your image editor. Then overlay that image on top of your image. The image underneath will show through the transparent region in the center of your rounded corners image making anything appear "rounded"

slf
+19  A: 

You can use CoreGraphics to create a path for a round rectangle with this code snippet:

static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight)
{
 float fw, fh;
 if (ovalWidth == 0 || ovalHeight == 0) {
  CGContextAddRect(context, rect);
  return;
 }
 CGContextSaveGState(context);
 CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));
 CGContextScaleCTM (context, ovalWidth, ovalHeight);
 fw = CGRectGetWidth (rect) / ovalWidth;
 fh = CGRectGetHeight (rect) / ovalHeight;
 CGContextMoveToPoint(context, fw, fh/2);
 CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);
 CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);
 CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);
 CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);
 CGContextClosePath(context);
 CGContextRestoreGState(context);
}

And then call CGContextClip(context); to clip it to the rectangle path. Now any drawing done, including drawing an image, will be clipped to the round rectangle shape.

As an example, assuming "image" is a UIImage, and this is in a drawRect: method:

CGContextRef context = UIGraphicsGetCurrentContext();
CGGraphicsSaveGState(context);
addRoundRectToPath(context, self.frame, 10, 10);
CGContextClip(context);
[image drawInRect:self.frame];
CGContextRestoreGState(context);
NilObject
up vote because math is cool
slf
That looks very useful, but I'm not familiar with the CG library. If I have a UIImageView/UIImage, where do I go from there?
erotsppa
You would want to implement the drawRect method on the view with the code I added above.
NilObject
Some minor corrections - the drawRect example contains two errors. Call addRoundedRectToPath (not addRoundRectToPath), and to save state call CGContextSaveGState (not CGGraphicsSaveGState).
stefpet
+7  A: 

Here is an even easier method that is available in iPhone 3.0 and up. Every View-based object has an associated layer. Each layer can have a corner radius set, this will give you just what you want:

    UIImageView * roundedView = [[UIImageView alloc] initWithImage: [UIImage imageNamed:@"wood.jpg"]];
    // Get the Layer of any view
CALayer * l = [roundedView layer];
[l setMasksToBounds:YES];
[l setCornerRadius:10.0];

    // You can even add a border
[l setBorderWidth:4.0];
[l setBorderColor:[[UIColor blueColor] CGColor]];
MagicSeth
The CoreGraphics Method above posted by NilObject is faster when you are dealing with animating items. Apparently the built in corner radius is not as efficient.
MagicSeth
Thanks! If anyone runs into trouble with this, be sure to #import <QuartzCore/QuartzCore.h> in your implementation file, else none of those methods will fly.
Joe D'Andrea
Here you're allocating a UIImageView object. This is not an option when you're dealing with images in UITableViews.
Sam V
A: 

I am getting warning no method found when using [l setMasksToBounds:YES]; ...

any help?

david
+1  A: 

You need to import QuartzCore/QuartzCore.h

XCode
A: 

thanx MagicSeth :) it saved a lot of my time...

Vaibhav Saran