How to set UIImageView with rounded corners for aspect fit mode
Asked Answered
K

9

27

I usually use the following code to set rounded corners.

imageView.layer.cornerRadius = 10

It works when the imageView is set at Aspect Fill.

But when the imageView is set to Aspect Fit mode, and the ratio between imageView and picture are different. The rounded corners effect won't be able to tell.

enter image description here

The background color is set to green for showing the rounded corners.

Is there any way to set 'real image part' to rounded corners.

Thank you in advance for your answers.

Kerekes answered 23/1, 2016 at 10:4 Comment(2)
Refer this https://mcmap.net/q/23530/-ios-image-view-aspect-fit-with-corner-radiusNavel
Or resize the image view to fitHaematozoon
G
49

Use this extension to UIImageView:

extension UIImageView
{
    func roundCornersForAspectFit(radius: CGFloat)
    {
        if let image = self.image {

            //calculate drawingRect
            let boundsScale = self.bounds.size.width / self.bounds.size.height
            let imageScale = image.size.width / image.size.height

            var drawingRect: CGRect = self.bounds

            if boundsScale > imageScale {
                drawingRect.size.width =  drawingRect.size.height * imageScale
                drawingRect.origin.x = (self.bounds.size.width - drawingRect.size.width) / 2
            } else {
                drawingRect.size.height = drawingRect.size.width / imageScale
                drawingRect.origin.y = (self.bounds.size.height - drawingRect.size.height) / 2
            }
            let path = UIBezierPath(roundedRect: drawingRect, cornerRadius: radius)
            let mask = CAShapeLayer()
            mask.path = path.cgPath
            self.layer.mask = mask
        }
    }
}

Without calling this function

After calling this extension method

Garb answered 23/1, 2016 at 11:1 Comment(4)
Hi, how could this work within a CollectionViewCell? The bound return empty every time..Dit
I have asked a question, I really want to use the functionality you created @Arun Ammannaya but on a collection view cell, but I cannot for the life of me get it to work.. #50896845Dit
Beautiful extension!Forwarding
Seems reallllly slow, perhaps iOS updated in a relevant way since this was posted (yes, it is a very old answer)Poppyhead
K
5

Swift 3 version of the helpful, accepted answer is over here!

extension UIImageView {
func roundCornersForAspectFit(radius: CGFloat)
{
    if let image = self.image {

        //calculate drawingRect
        let boundsScale = self.bounds.size.width / self.bounds.size.height
        let imageScale = image.size.width / image.size.height

        var drawingRect : CGRect = self.bounds

        if boundsScale > imageScale {
            drawingRect.size.width =  drawingRect.size.height * imageScale
            drawingRect.origin.x = (self.bounds.size.width - drawingRect.size.width) / 2
        }else {
            drawingRect.size.height = drawingRect.size.width / imageScale
            drawingRect.origin.y = (self.bounds.size.height - drawingRect.size.height) / 2
        }
        let path = UIBezierPath(roundedRect: drawingRect, cornerRadius: radius)
        let mask = CAShapeLayer()
        mask.path = path.cgPath
        self.layer.mask = mask
        }
    }
}
Kwei answered 20/12, 2016 at 3:29 Comment(0)
G
3

Try this may help you:

import UIKit


class ViewController: UIViewController{

    @IBOutlet weak var myImageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        myImageView.contentMode = UIViewContentMode.ScaleAspectFit
        myImageView.clipsToBounds = true
        //myImageView.layer.cornerRadius = 10.0
        myImageView.layer.masksToBounds = true

        let simpleImage = UIImage(named:"ipad5_einladung.jpg")
        let corneredImage = generateRoundCornerImage(simpleImage!, radius: 10)

        //Set cornered Image
        myImageView.image = corneredImage;

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    func generateRoundCornerImage(image : UIImage , radius : CGFloat) -> UIImage {

        let imageLayer = CALayer()
        imageLayer.frame = CGRectMake(0, 0, image.size.width, image.size.height)
        imageLayer.contents = image.CGImage
        imageLayer.masksToBounds = true
        imageLayer.cornerRadius = radius

        UIGraphicsBeginImageContext(image.size)
        imageLayer.renderInContext(UIGraphicsGetCurrentContext())
        let roundedImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return roundedImage
    }

}
Gingili answered 23/1, 2016 at 10:46 Comment(0)
M
2

This is the accepted answer converted to Objective-C:

@implementation UIImageView(Utils)

- (void)roundCornersForAspectFitWithRadius:(CGFloat)cornerRadius {
    if (self.image) {
        double boundsScale = self.bounds.size.width / self.bounds.size.height;
        double imageScale = self.image.size.width / self.image.size.height;

        CGRect drawingRect = self.bounds;

        if (boundsScale > imageScale) {
            drawingRect.size.width = drawingRect.size.height * imageScale;
            drawingRect.origin.x = (self.bounds.size.width - drawingRect.size.width) / 2;
        }
        else {
            drawingRect.size.height = drawingRect.size.width / imageScale;
            drawingRect.origin.y = (self.bounds.size.height - drawingRect.size.height) / 2;
        }
        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:drawingRect cornerRadius:cornerRadius];
        CAShapeLayer *mask = [CAShapeLayer new];
        [mask setPath:path.CGPath];
        [self.layer setMask:mask];
    }
}

@end
Marine answered 3/4, 2018 at 17:59 Comment(1)
Well am new to objective c. Could you plese tell me how to put this in the category of UIImageView. Plus the implementation of how to use the method with imageSteapsin
S
1

You first need to set the width and height to the same value. Then set the image properties like so:

imgProfile_Pic.layer.cornerRadius = cell.imgProfile_Pic.frame.size.height / 2
imgProfile_Pic.layer.borderWidth = 3.0
imgProfile_Pic.layer.borderColor = UIColor.white.cgColor
imgProfile_Pic.clipsToBounds = true
imgProfile_Pic.layoutIfNeeded()
Soil answered 23/1, 2016 at 10:47 Comment(0)
S
0

I wanted to comment on Arun's answer to help those who are having issues with doing Arun's method but in Collection View, you have to initiate the imageView's frame as the collection view cell's frame.

i.e.

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "identifier", for: indexPath) as UICollectionViewCell
let imageView = UIImageView(frame: cell.frame)

obviously you want to refactor that and stuff but you get the idea.

Scurrilous answered 12/7, 2020 at 5:18 Comment(0)
C
0

If you use SDWebImage in your project, you can do the following:

myUIImageView.image = myUIImage.sd_roundedCornerImage(withRadius: 24, corners: .allCorners, borderWidth: 0, borderColor: nil)

Cooperman answered 11/3, 2022 at 5:52 Comment(0)
D
0

Here a solution using the recommended renderer UIGraphicsImageRenderer:

extension UIImageView {
    func setRoundedCorners(radius: CGFloat) {
        guard let image = self.image else {
            fatalError("Set image first")
        }
        let imageLayer = CALayer()
        imageLayer.frame = CGRectMake(0, 0, image.size.width, image.size.height)
        imageLayer.contents = image.cgImage
        imageLayer.masksToBounds = true
        imageLayer.cornerRadius = radius
        
        let renderer = UIGraphicsImageRenderer(
            bounds: CGRectMake(0, 0, image.size.width, image.size.height),
            format:  UIGraphicsImageRendererFormat(for: traitCollection)
        )
        let roundedImage = renderer.image { action in
            imageLayer.render(in: action.cgContext)
        }
        
        self.image = roundedImage
    }
}

Then you can just do:

let imageView = UIImageView(image: <your image>)
imageView. setRoundedCorners(radius: 16)
Dejadeject answered 31/5, 2023 at 12:35 Comment(0)
O
-3

This is very simple to round the image view like this:

self.profileImageView?.clipsToBounds = true
self.profileImageView!.layer.cornerRadius = 10
self.profileImageView?.layer.borderWidth = 1.0
self.profileImageView?.contentMode = .ScaleAspectFit

But for making image view rounded with image ratio, I think you have to set image view for ScaleAspectFill mode.

Offshoot answered 23/1, 2016 at 12:8 Comment(1)
His question was "How to set UIImageView with rounded corners for aspect fit mode" he is not asking for scaling the imageHonaker

© 2022 - 2025 — McMap. All rights reserved.