Making a UIImage to a circle form

24,431

Solution 1

try this code

yourImageView.layer.cornerRadius = yourImageView.frame.size.height /2;
yourImageView.layer.masksToBounds = YES;
yourImageView.layer.borderWidth = 0;

this show image like ios 7 circle image thanks

Solution 2

This might help you, pass corner radius as half of the reference view where you want to display the image or you can set a custom rect,

eg. In my case I want to display the image on a "imageView", so the corner radius in this case would be imageView.frame.size.width/2

- (void)displayImage
{
    imageView.image = [self getRoundedRectImageFromImage:@"Test.png" onReferenceView:imageView withCornerRadius: imageView.frame.size.width/2];
}



- (UIImage *)getRoundedRectImageFromImage :(UIImage *)image onReferenceView :(UIImageView*)imageView withCornerRadius :(float)cornerRadius
{
    UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0);
    [[UIBezierPath bezierPathWithRoundedRect:imageView.bounds
                                cornerRadius:cornerRadius] addClip];
    [image drawInRect:imageView.bounds];
    UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return finalImage;
}

Solution 3

Sorry for ugly formatting. Better version of aToz's answer.

@interface UIImage (CircleMask)

+ (UIImage *)roundedRectImageFromImage :(UIImage *)image
                                  size :(CGSize)imageSize
                      withCornerRadius :(float)cornerRadius;

@end

@implementation UIImage(CircleMask)

+(UIImage*)roundedRectImageFromImage:(UIImage *)image
                                size:(CGSize)imageSize
                    withCornerRadius:(float)cornerRadius
{
    UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0);   //  <= notice 0.0 as third scale parameter. It is important cause default draw scale ≠ 1.0. Try 1.0 - it will draw an ugly image..
    CGRect bounds = (CGRect){CGPointZero,imageSize};
    [[UIBezierPath bezierPathWithRoundedRect:bounds
                                cornerRadius:cornerRadius] addClip];
    [image drawInRect:bounds];
    UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return finalImage;
}

@end

The same thing in Swift:

extension UIImage{

    class func roundedRectImageFromImage(image:UIImage,imageSize:CGSize,cornerRadius:CGFloat)->UIImage{
        UIGraphicsBeginImageContextWithOptions(imageSize, false, 0.0)
        let bounds = CGRect(origin: CGPointZero, size: imageSize)
        UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).addClip()
        image.drawInRect(bounds)
        let finalImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return finalImage
    }
    
}

Solution 4

A better version of aToz's and fnc12's answers (in Swift):

extension UIImage
{
    func roundImage() -> UIImage
    {
        let newImage = self.copy() as! UIImage
        let cornerRadius = self.size.height/2
        UIGraphicsBeginImageContextWithOptions(self.size, false, 1.0)
        let bounds = CGRect(origin: CGPointZero, size: self.size)
        UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).addClip()
        newImage.drawInRect(bounds)
        let finalImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return finalImage
    }
}

Usage:

self.userImageView.image = image.roundedImage()

Solution 5

Felt like I should throw my hat into the ring. An effective, compact Swift 5 solution:

extension UIImage {

    var rounded: UIImage? {
        UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
        defer { UIGraphicsEndImageContext() }
        let bounds = CGRect(origin: .zero, size: size)
        UIBezierPath(roundedRect: bounds, cornerRadius: size.height/2.0).addClip()
        draw(in: bounds)
        return UIGraphicsGetImageFromCurrentImageContext()
    }

}

Share:
24,431
Shahar Nechmad
Author by

Shahar Nechmad

Updated on October 08, 2020

Comments

  • Shahar Nechmad
    Shahar Nechmad over 3 years

    I have been trying to mask a UIImage into a circle. I'm using now the code that has been popular on other answers here, but although I do get a circle its edges are very jagged and not smooth. Anyone can help? I do I get a perfect, smooth circle?

    The code I'm using to create the mask is:

      (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
    
        CGImageRef imageNoAlpha = image.CGImage;
    
        CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
    
        CGFloat width = CGImageGetWidth(imageNoAlpha);
        CGFloat height = CGImageGetWidth(imageNoAlpha);
    
        CGContextRef ctxWithAlpha = CGBitmapContextCreate(nil, width, height, 8, 4*width, cs, kCGImageAlphaPremultipliedFirst);
    
        CGContextDrawImage(ctxWithAlpha, CGRectMake(0, 0, width, height), imageNoAlpha);
    
        CGImageRef imageWithAlpha = CGBitmapContextCreateImage(ctxWithAlpha);
    
        CGImageRef maskRef = maskImage.CGImage; 
    
        CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                            CGImageGetHeight(maskRef),
                                            CGImageGetBitsPerComponent(maskRef),
                                            CGImageGetBitsPerPixel(maskRef),
                                            CGImageGetBytesPerRow(maskRef),
                                            CGImageGetDataProvider(maskRef), NULL, false);
    
        CGImageRef masked = CGImageCreateWithMask(imageWithAlpha, mask);
    
        UIImage* retImage= [UIImage imageWithCGImage:masked];
        UIImage* retImageFixed = [retImage transparentBorderImage:1];
    
        CGImageRelease(mask);
        CGImageRelease(masked);
        CGImageRelease(imageWithAlpha);
        CGContextRelease(ctxWithAlpha);
        CGColorSpaceRelease(cs);
    
        return retImageFixed;
    

    Thanks in advance...

  • xiaowl
    xiaowl about 10 years
    FYI, this solution makes scrolling in table view sluggish. @aToz's solution works well.
  • aLFaRSi
    aLFaRSi almost 10 years
    Its working perfectly in tableView scrolling, i don't see any problem with it, my tableView contain 246 rows each row loads image from server and still working perfectly
  • fnc12
    fnc12 over 9 years
    The third parameter in UIGraphicsBeginImageContextWithOptions must be 0.0 instead of 1.0. Because 1.0 draws very ugly
  • scord
    scord over 8 years
    @aLFaRSi what type of device are you running? Bad performing code doesnt always manifest itself at first. There may be a theory proof or benchmark both methods.
  • Chen Li Yong
    Chen Li Yong about 8 years
    @fnc12 thank you! I was wondering why the result was blurry and ugly.
  • khunshan
    khunshan about 8 years
    can we crop and round for non-square images?
  • Jeff
    Jeff about 7 years
    @alFaRSi. You got lucky ;)
  • grebulon
    grebulon over 3 years
    CGPointZero is deprecated, use: CGRect(origin: .zero, size: imageSize) instead.
  • hotdogsoup.nl
    hotdogsoup.nl over 3 years
    This is using an UIImageView whereas the topic starter asks for a circle masked UIImage.