Tutorial :UIImage rounded corners



Question:

I try to get rounded corners on a UIImage, what I read so far, the easiest way is to use a mask images. For this I used code from TheElements iPhone Example and some image resize code I found. My problem is that resizedImage is always nil and I don't 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;  }  


Solution:1

If you are using a UIImageView to display the image you can simply do the following:

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

And to add a border:

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

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


Solution:2

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();  


Solution:3

I created an UIImage-extension in swift, based on @epatel's great 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 a storyboard:

storyboard


Solution:4

The problem was the use of CGImageCreateWithMask which returned an all black image. The solution I found was 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;  


Solution:5

You aren't actually doing anything other than scaling there. What you need to do is to "mask" the corners of the image by clipping it with a CGPath. For instance -

 - (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.


Solution:6

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;  }  


Solution:7

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;  }  

Cheers !!!


Solution:8

The reason it worked with clipping, not with masking, seems to be the color space.

Apple Documentation's below.

mask A mask. If the mask is an image, it must be in the DeviceGray color space, must not have an alpha component, and may not itself be masked by an image mask or a masking color. If the mask is not the same size as the image specified by the image parameter, then Quartz scales the mask to fit the image.


Solution:9

Found out the best and simple way of doing it is as follows (no answer did that):

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

Pretty simple and done this right.


Solution:10

See here... IMO unless you absolutely need to do it in code, just overlay an image on top.

Something along the lines of...

- (void)drawRect:(CGRect)rect   {      // Drawing code      [backgroundImage drawInRect:rect];      [buttonOverlay drawInRect:rect];      }  


Solution:11

For Creating a Round Corner image 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 else

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 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;  


Solution:12

It's very easy to create a rounded image when you make use of the image dimension.

cell.messageImage.layer.cornerRadius = image.size.width / 2  cell.messageImage.layer.masksToBounds = true  


Solution:13

I was struggling to round the corners of a UIImage box in my storyboard. I had a IBOutlet for my UIImage called image. After reading a bunch of posts on here, I simply added 3 lines and that 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.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »