1

The image becomes blurry once applying roundImage: Making a UIImage to a circle form

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
    }
}
Community
  • 1
  • 1
Tim Nuwin
  • 2,775
  • 2
  • 29
  • 63

4 Answers4

2

try this one

let image = UIImageView(frame: CGRectMake(0, 0, 100, 100))

Birendra
  • 623
  • 1
  • 5
  • 17
2

Why are you using bezierpath? Just set cornerradius for uiimageview.

If your image is larger than the imageview then you have to resize your image to your imageview size and then set cornerradius for that uiimageview.

It will work. Works for me

Replace the following line

UIGraphicsBeginImageContextWithOptions(self.size, false, 1.0)

with

UIGraphicsBeginImageContextWithOptions(self.size, view.opaque , 0.0)
Balaji Kondalrayal
  • 1,743
  • 3
  • 19
  • 38
2

I recommend that you can use AlamofireImage (https://github.com/Alamofire/AlamofireImage)

It's very easily to make rounded image or circle image without losing quality.

just like this:

let image = UIImage(named: "unicorn")!
let radius: CGFloat = 20.0

let roundedImage = image.af_imageWithRoundedCornerRadius(radius)
let circularImage = image.af_imageRoundedIntoCircle()

Voila!

Joey Wong
  • 185
  • 1
  • 4
1

Your issue is that you are using scale 1, which is the lowest "quality". Setting the scale to 0 will use the device scale, which just uses the image as is.

A side note: Functions inside a class that return a new instance of that class can be implemented as class functions. This makes it very clear what the function does. It does not manipulate the existing image. It returns a new one.

Since you were talking about circles, I also corrected your code so it will now make a circle of any image and crop it. You might want to center this.

extension UIImage {

    class func roundImage(image : UIImage) -> UIImage? {

        // copy
        guard let newImage = image.copy() as? UIImage else {
            return nil
        }
        // start context
        UIGraphicsBeginImageContextWithOptions(newImage.size, false, 0.0)

        // bounds
        let cornerRadius = newImage.size.height / 2
        let minDim = min(newImage.size.height, newImage.size.width)
        let bounds = CGRect(origin: CGPointZero, size: CGSize(width: minDim, height: minDim))
        UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).addClip()

        // new image
        newImage.drawInRect(bounds)
        let finalImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        // crop
        let maybeCrop = UIImage.crop(finalImage, cropRect: bounds)

        return maybeCrop

    }

    class func crop(image: UIImage, cropRect : CGRect) -> UIImage? {

        guard let imgRef = CGImageCreateWithImageInRect(image.CGImage, cropRect) else {
            return nil
        }
        return UIImage(CGImage: imgRef)
    }
}
R Menke
  • 8,183
  • 4
  • 35
  • 63