Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rounded Corners on UIImage

I'm trying to draw images on the iPhone using with rounded corners, a la the contact images in the Contacts app. I've got code that generally work, but it occasionally crashes inside of the UIImage drawing routines with an EXEC_BAD_ACCESS - KERN_INVALID_ADDRESS. I thought this might be related to the cropping question I asked a few weeks back, but I believe I'm setting up the clipping path correctly.

Here's the code I'm using - when it doesn't crash, the result looks fine and anybody looking to get a similar look is free to borrow the code.

- (UIImage *)borderedImageWithRect: (CGRect)dstRect radius:(CGFloat)radius {     UIImage *maskedImage = nil;      radius = MIN(radius, .5 * MIN(CGRectGetWidth(dstRect), CGRectGetHeight(dstRect)));     CGRect interiorRect = CGRectInset(dstRect, radius, radius);      UIGraphicsBeginImageContext(dstRect.size);     CGContextRef maskedContextRef = UIGraphicsGetCurrentContext();     CGContextSaveGState(maskedContextRef);      CGMutablePathRef borderPath = CGPathCreateMutable();     CGPathAddArc(borderPath, NULL, CGRectGetMinX(interiorRect), CGRectGetMinY(interiorRect), radius, PNDegreeToRadian(180), PNDegreeToRadian(270), NO);     CGPathAddArc(borderPath, NULL, CGRectGetMaxX(interiorRect), CGRectGetMinY(interiorRect), radius, PNDegreeToRadian(270.0), PNDegreeToRadian(360.0), NO);     CGPathAddArc(borderPath, NULL, CGRectGetMaxX(interiorRect), CGRectGetMaxY(interiorRect), radius, PNDegreeToRadian(0.0), PNDegreeToRadian(90.0), NO);     CGPathAddArc(borderPath, NULL, CGRectGetMinX(interiorRect), CGRectGetMaxY(interiorRect), radius, PNDegreeToRadian(90.0), PNDegreeToRadian(180.0), NO);      CGContextBeginPath(maskedContextRef);     CGContextAddPath(maskedContextRef, borderPath);     CGContextClosePath(maskedContextRef);     CGContextClip(maskedContextRef);      [self drawInRect: dstRect];      maskedImage = UIGraphicsGetImageFromCurrentImageContext();     CGContextRestoreGState(maskedContextRef);     UIGraphicsEndImageContext();      return maskedImage; } 

and here's the crash log. It looks the same whenever I get one of these crashes

 Exception Type:  EXC_BAD_ACCESS (SIGSEGV) Exception Codes: KERN_INVALID_ADDRESS at 0x6e2e6181 Crashed Thread:  0  Thread 0 Crashed: 0   com.apple.CoreGraphics          0x30fe56d8 CGGStateGetRenderingIntent + 4 1   libRIP.A.dylib                  0x33c4a7d8 ripc_RenderImage + 104 2   libRIP.A.dylib                  0x33c51868 ripc_DrawImage + 3860 3   com.apple.CoreGraphics          0x30fecad4 CGContextDelegateDrawImage + 80 4   com.apple.CoreGraphics          0x30feca40 CGContextDrawImage + 368 5   UIKit                           0x30a6a708 -[UIImage drawInRect:blendMode:alpha:] + 1460 6   UIKit                           0x30a66904 -[UIImage drawInRect:] + 72 7   MyApp                           0x0003f8a8 -[UIImage(PNAdditions) borderedImageWithRect:radius:] (UIImage+PNAdditions.m:187) 
like image 716
Jablair Avatar asked Oct 15 '08 16:10

Jablair


People also ask

How do I round the corners of an image in swift?

To make an image with round corners or to make any view or button or any UI element with round corners in swift, we need to access the corner radius property of its layer. Every UI element in iOS is based on a layer.

How do you add corner radius to a storyboard?

Select the view that you want to round and open its Identity Inspector. In the User Defined Runtime Attributes section, add the following two entries: Key Path: layer. cornerRadius , Type: Number, Value: (whatever radius you want)


Video Answer


2 Answers

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]]; 
like image 55
MagicSeth Avatar answered Oct 15 '22 23:10

MagicSeth


I'm gonna go ahead here and actually answer the question in the title.

Try this category.

UIImage+additions.h

#import <UIKit/UIKit.h>  @interface UIImage (additions) -(UIImage*)makeRoundCornersWithRadius:(const CGFloat)RADIUS; @end 

UIImage+additions.m

#import "UIImage+additions.h"  @implementation UIImage (additions) -(UIImage*)makeRoundCornersWithRadius:(const CGFloat)RADIUS {     UIImage *image = self;      // Begin a new image that will be the new image with the rounded corners     // (here with the size of an UIImageView)     UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);      const CGRect RECT = CGRectMake(0, 0, image.size.width, image.size.height);     // Add a clip before drawing anything, in the shape of an rounded rect     [[UIBezierPath bezierPathWithRoundedRect:RECT cornerRadius:RADIUS] addClip];     // Draw your image     [image drawInRect:RECT];      // Get the image, here setting the UIImageView image     //imageView.image     UIImage* imageNew = UIGraphicsGetImageFromCurrentImageContext();      // Lets forget about that we were drawing     UIGraphicsEndImageContext();      return imageNew; } @end 
like image 39
Jonny Avatar answered Oct 15 '22 23:10

Jonny