UIImage rounded corners

I am trying to get rounded corners on a UIImage that I have read so far, the easiest way is to use mask images. For this, I used the code from TheElements iPhone example and some image resizing code that I found. My problem is that resizedImage is always zero and I did not find the error ...

- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize { CGSize imageSize = [self size]; float width = imageSize.width; float height = imageSize.height; // scaleFactor will be the fraction that we'll // use to adjust the size. For example, if we shrink // an image by half, scaleFactor will be 0.5. the // scaledWidth and scaledHeight will be the original, // multiplied by the scaleFactor. // // IMPORTANT: the "targetHeight" is the size of the space // we're drawing into. The "scaledHeight" is the height that // the image actually is drawn at, once we take into // account the ideal of maintaining proportions float scaleFactor = 0.0; float scaledWidth = targetSize.width; float scaledHeight = targetSize.height; CGPoint thumbnailPoint = CGPointMake(0,0); // since not all images are square, we want to scale // proportionately. To do this, we find the longest // edge and use that as a guide. if ( CGSizeEqualToSize(imageSize, targetSize) == NO ) { // use the longeset edge as a guide. if the // image is wider than tall, we'll figure out // the scale factor by dividing it by the // intended width. Otherwise, we'll use the // height. float widthFactor = targetSize.width / width; float heightFactor = targetSize.height / height; if ( widthFactor < heightFactor ) scaleFactor = widthFactor; else scaleFactor = heightFactor; // ex: 500 * 0.5 = 250 (newWidth) scaledWidth = width * scaleFactor; scaledHeight = height * scaleFactor; // center the thumbnail in the frame. if // wider than tall, we need to adjust the // vertical drawing point (y axis) if ( widthFactor < heightFactor ) thumbnailPoint.y = (targetSize.height - scaledHeight) * 0.5; else if ( widthFactor > heightFactor ) thumbnailPoint.x = (targetSize.width - scaledWidth) * 0.5; } CGContextRef mainViewContentContext; CGColorSpaceRef colorSpace; colorSpace = CGColorSpaceCreateDeviceRGB(); // create a bitmap graphics context the size of the image mainViewContentContext = CGBitmapContextCreate (NULL, targetSize.width, targetSize.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast); // free the rgb colorspace CGColorSpaceRelease(colorSpace); if (mainViewContentContext==NULL) return NULL; //CGContextSetFillColorWithColor(mainViewContentContext, [[UIColor whiteColor] CGColor]); //CGContextFillRect(mainViewContentContext, CGRectMake(0, 0, targetSize.width, targetSize.height)); CGContextDrawImage(mainViewContentContext, CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledWidth, scaledHeight), self.CGImage); // Create CGImageRef of the main view bitmap content, and then // release that bitmap context CGImageRef mainViewContentBitmapContext = CGBitmapContextCreateImage(mainViewContentContext); CGContextRelease(mainViewContentContext); CGImageRef maskImage = [[UIImage imageNamed:@"Mask.png"] CGImage]; CGImageRef resizedImage = CGImageCreateWithMask(mainViewContentBitmapContext, maskImage); CGImageRelease(mainViewContentBitmapContext); // convert the finished resized image to a UIImage UIImage *theImage = [UIImage imageWithCGImage:resizedImage]; // image is retained by the property setting above, so we can // release the original CGImageRelease(resizedImage); // return the image return theImage; } 
+56
iphone cocoa-touch
Nov 04 '08 at 15:25
source share
13 answers

The problem was using CGImageCreateWithMask, which returned the entire black image. The solution I found is to use CGContextClipToMask instead:

 CGContextRef mainViewContentContext; CGColorSpaceRef colorSpace; colorSpace = CGColorSpaceCreateDeviceRGB(); // create a bitmap graphics context the size of the image mainViewContentContext = CGBitmapContextCreate (NULL, targetSize.width, targetSize.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast); // free the rgb colorspace CGColorSpaceRelease(colorSpace); if (mainViewContentContext==NULL) return NULL; CGImageRef maskImage = [[UIImage imageNamed:@"mask.png"] CGImage]; CGContextClipToMask(mainViewContentContext, CGRectMake(0, 0, targetSize.width, targetSize.height), maskImage); CGContextDrawImage(mainViewContentContext, CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledWidth, scaledHeight), self.CGImage); // Create CGImageRef of the main view bitmap content, and then // release that bitmap context CGImageRef mainViewContentBitmapContext = CGBitmapContextCreateImage(mainViewContentContext); CGContextRelease(mainViewContentContext); // convert the finished resized image to a UIImage UIImage *theImage = [UIImage imageWithCGImage:mainViewContentBitmapContext]; // image is retained by the property setting above, so we can // release the original CGImageRelease(mainViewContentBitmapContext); // return the image return theImage; 
+14
Mar 30 '09 at 20:00
source share

If you use UIImageView to display an image, you can simply do the following:

 imageView.layer.cornerRadius = 5.0; imageView.layer.masksToBounds = YES; 

And add a border:

 imageView.layer.borderColor = [UIColor lightGrayColor].CGColor; imageView.layer.borderWidth = 1.0; 

I believe that you have to import <QuartzCore/QuartzCore.h> and reference it for the above code to work.

+199
Dec 02 '09 at 17:36
source share

How about these lines ...

 // Get your image somehow UIImage *image = [UIImage imageNamed:@"image.jpg"]; // Begin a new image that will be the new image with the rounded corners // (here with the size of an UIImageView) UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0); // Add a clip before drawing anything, in the shape of an rounded rect [[UIBezierPath bezierPathWithRoundedRect:imageView.bounds cornerRadius:10.0] addClip]; // Draw your image [image drawInRect:imageView.bounds]; // Get the image, here setting the UIImageView image imageView.image = UIGraphicsGetImageFromCurrentImageContext(); // Lets forget about that we were drawing UIGraphicsEndImageContext(); 
+83
Nov 21 2018-11-11T00:
source share

I created a UIImage -extension in swift based on @epatel's excellent answer:

 extension UIImage{ var roundedImage: UIImage { let rect = CGRect(origin:CGPoint(x: 0, y: 0), size: self.size) UIGraphicsBeginImageContextWithOptions(self.size, false, 1) UIBezierPath( roundedRect: rect, cornerRadius: self.size.height ).addClip() self.drawInRect(rect) return UIGraphicsGetImageFromCurrentImageContext() } } 

Tested in storyboard:

storyboard

+20
Aug 31 '15 at 3:08
source share

In fact, you are not doing anything but scaling. What you need to do is to "mask" the corners of the image by cutting it off with CGPath. For example -

  - (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextBeginTransparencyLayerWithRect(context, self.frame, NULL); CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0); CGFloat roundRadius = (radius) ? radius : 12.0; CGFloat minx = CGRectGetMinX(self.frame), midx = CGRectGetMidX(self.frame), maxx = CGRectGetMaxX(self.frame); CGFloat miny = CGRectGetMinY(self.frame), midy = CGRectGetMidY(self.frame), maxy = CGRectGetMaxY(self.frame); // draw the arcs, handle paths CGContextMoveToPoint(context, minx, midy); CGContextAddArcToPoint(context, minx, miny, midx, miny, roundRadius); CGContextAddArcToPoint(context, maxx, miny, maxx, midy, roundRadius); CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, roundRadius); CGContextAddArcToPoint(context, minx, maxy, minx, midy, roundRadius); CGContextClosePath(context); CGContextDrawPath(context, kCGPathFill); CGContextEndTransparencyLayer(context); } 

I suggest checking out the Quartz 2D programming guide or some other samples.

+5
Nov 04 '08 at 17:16
source share
 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); } + (UIImage *)imageWithRoundCorner:(UIImage*)img andCornerSize:(CGSize)size { UIImage * newImage = nil; if( nil != img) { @autoreleasepool { int w = img.size.width; int h = img.size.height; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst); CGContextBeginPath(context); CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height); addRoundedRectToPath(context, rect, size.width, size.height); CGContextClosePath(context); CGContextClip(context); CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage); CGImageRef imageMasked = CGBitmapContextCreateImage(context); CGContextRelease(context); CGColorSpaceRelease(colorSpace); [img release]; newImage = [[UIImage imageWithCGImage:imageMasked] retain]; CGImageRelease(imageMasked); } } return newImage; } 
+4
May 16 '12 at 13:16
source share

Hi guys, try this code,

 + (UIImage *)roundedRectImageFromImage:(UIImage *)image withRadious:(CGFloat)radious { if(radious == 0.0f) return image; if( image != nil) { CGFloat imageWidth = image.size.width; CGFloat imageHeight = image.size.height; CGRect rect = CGRectMake(0.0f, 0.0f, imageWidth, imageHeight); UIWindow *window = [[[UIApplication sharedApplication] windows] objectAtIndex:0]; const CGFloat scale = window.screen.scale; UIGraphicsBeginImageContextWithOptions(rect.size, NO, scale); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextBeginPath(context); CGContextSaveGState(context); CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect)); CGContextScaleCTM (context, radious, radious); CGFloat rectWidth = CGRectGetWidth (rect)/radious; CGFloat rectHeight = CGRectGetHeight (rect)/radious; CGContextMoveToPoint(context, rectWidth, rectHeight/2.0f); CGContextAddArcToPoint(context, rectWidth, rectHeight, rectWidth/2.0f, rectHeight, radious); CGContextAddArcToPoint(context, 0.0f, rectHeight, 0.0f, rectHeight/2.0f, radious); CGContextAddArcToPoint(context, 0.0f, 0.0f, rectWidth/2.0f, 0.0f, radious); CGContextAddArcToPoint(context, rectWidth, 0.0f, rectWidth, rectHeight/2.0f, radious); CGContextRestoreGState(context); CGContextClosePath(context); CGContextClip(context); [image drawInRect:CGRectMake(0.0f, 0.0f, imageWidth, imageHeight)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } return nil; } 

Greetings !!!

+2
Dec 12 '12 at 9:23
source share

The reason he worked with clipping rather than disguise seems to be color space.

Apple documentation below.

mask mask. If the mask is an image, it must be in the DeviceGray color space, must not have an alpha component, and itself cannot be masked using an image mask or a masking color. If the mask does not match the image specified by the image parameter, then Quartz scales the mask to fit the image.

+1
Oct 15 '09 at 13:57
source share

See here ... IMO, if you absolutely do not need to do this in code, just overlay the image on top.

Something along the lines ...

 - (void)drawRect:(CGRect)rect { // Drawing code [backgroundImage drawInRect:rect]; [buttonOverlay drawInRect:rect]; } 
0
Nov 04 '08 at 17:11
source share

To create an image with a round angle, we can use quartzcore.

First How to add QuartzCore framework?

 Click project -Targets ->project ->BuildPhase ->Link Binary with Libraries ->Then click + symbol finally select from list and add it 

or more

 Click project -Targets ->Targets ->general ->Linked Frameworks and Libraries ->Then click + symbol finally select from list and add the QuartzCore framework 

Now import

 #import <QuartzCore/QuartzCore.h> 

in your ViewController

Then in the viewDidLoad method

 self.yourImageView.layer.cornerRadius = 5.0; self.yourImageView.layer.borderWidth = 1.0f; self.yourImageView.layer.borderColor = [UIColor blackColor].CGColor; self.yourImageView.layer.masksToBounds = YES; 
0
Aug 31 '15 at 9:39
source share

It is very simple to create a rounded image when you use image size.

 cell.messageImage.layer.cornerRadius = image.size.width / 2 cell.messageImage.layer.masksToBounds = true 
0
Feb 25 '17 at 9:08
source share

Found the best and easiest way to do this as follows (the answer did not answer):

 UIImageView *imageView; imageView.layer.cornerRadius = imageView.frame.size.width/2.0f; imageView.layer.masksToBounds = TRUE; 

Pretty simple and done right.

0
Jul 12 '17 at 9:15 on
source share

I struggled to go around the corners of the UIImage drawer in my storyboard. I had an IBOutlet for my UIImage called image. After reading a bunch of posts here, I just added 3 lines and it worked perfectly.

 import UIKit 

Then in viewDidLoad:

 image.layer.cornerRadius = 20.0 image.layer.masksToBounds = true 

This is for iOS 11.1 in Xcode 9.

0
Nov 27 '17 at 19:16
source share



All Articles