【问题标题】:UIImage with the corner round itself带有圆角的 UIImage
【发布时间】:2022-01-12 01:55:51
【问题描述】:

由于自动布局功能,我尝试使用 UIImage 圆角半径而不是 UIImageView。照片太大时圆角半径太细,比如4k x 4k,但是当照片很小,比如500 x 500时,圆角半径太大。不管照片大小,我都希望圆角半径为25。您有什么建议吗?

我从中尝试了以下代码,但它并没有解决我的问题。: https://newbedev.com/how-to-set-corner-radius-to-uiimage-not-uiimageview-in-ios-swift

我的目标是让圆角半径等于任何照片的大小。我测试了图像名称“demo”为4,000 x 4,000,圆角半径为5,“demo2”为500 x 500,圆角半径为50。

这是我的完整代码:

class TheCountdownDetails: UIViewController {
    let photoPreview = UIImageView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        photoPreview.translatesAutoresizingMaskIntoConstraints = false
        photoPreview.contentMode = .scaleAspectFit
        view.addSubview(photoPreview)
        photoPreview.topAnchor.constraint(equalTo: view.topAnchor, constant: 20).isActive = true
        photoPreview.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20).isActive = true
        photoPreview.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20).isActive = true
        photoPreview.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20).isActive = true
    }
    
    override func viewDidLayoutSubviews() {
        photoPreview.image = UIImage(named: "demo")?.withRoundedCorners(radius: 25)
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
    }
}


extension UIImage {
    public func withRoundedCorners(radius: CGFloat? = nil) -> UIImage? {
        let maxRadius = min(size.width, size.height) / 2
        let cornerRadius: CGFloat
        if let radius = radius, radius > 0 && radius <= maxRadius {
            cornerRadius = radius
        } else {
            cornerRadius = maxRadius
        }
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        let rect = CGRect(origin: .zero, size: size)
        UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).addClip()
        draw(in: rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

【问题讨论】:

    标签: ios swift uiimageview uiimage cornerradius


    【解决方案1】:

    如果您使用调试来检查从您的 withRoundedCorners(...) 函数返回的 UIImage,您会发现这两个图像实际上具有相同的圆角。

    问题是您在4k x 4k 图像上使用25 半径,在500 x 500 图像上使用25 半径,然后缩放它们以适合您的图像视图

    如果您将 imageView 的内容模式更改为:

    photoPreview.contentMode = .topLeft
    

    图像不会缩放,你会看到你得到了相同半径的圆角。

    因此,您需要在剪裁圆角的同时缩放图像。

    这是对您的扩展的修改:

    extension UIImage {
    
        func withRoundedCorners(radius: CGFloat? = nil, targetSize: CGSize) -> UIImage {
            // First, determine the scale factor that preserves aspect ratio
            let widthRatio = targetSize.width / size.width
            let heightRatio = targetSize.height / size.height
            
            let scaleFactor = min(widthRatio, heightRatio)
            
            // Compute the new image size that preserves aspect ratio
            let scaledImageSize = CGSize(
                width: size.width * scaleFactor,
                height: size.height * scaleFactor
            )
            
            let maxRadius = min(scaledImageSize.width, scaledImageSize.height) / 2
            let cornerRadius: CGFloat
            if let radius = radius, radius > 0 && radius <= maxRadius {
                cornerRadius = radius
            } else {
                cornerRadius = maxRadius
            }
    
            let newRect: CGRect = CGRect(origin: .zero, size: scaledImageSize)
            
            let renderer = UIGraphicsImageRenderer(size: newRect.size)
            
            let scaledImage = renderer.image { _ in
                UIBezierPath(roundedRect: newRect, cornerRadius: cornerRadius).addClip()
                self.draw(in: newRect)
            }
            
            return scaledImage
        }
    
    }
    

    还有一个示例控制器,将两个imageViews放在一个stack view中,这样我们就可以同时看到两个不同大小的图像:

    class TheCountdownDetails: UIViewController {
        
        let photoPreview1 = UIImageView()
        let photoPreview2 = UIImageView()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            
            let stack = UIStackView()
            stack.axis = .vertical
            stack.distribution = .fillEqually
            stack.spacing = 20
            stack.translatesAutoresizingMaskIntoConstraints = false
            
            stack.addArrangedSubview(photoPreview1)
            stack.addArrangedSubview(photoPreview2)
            view.addSubview(stack)
            
            photoPreview1.contentMode = .center
            photoPreview2.contentMode = .center
            
            let g = view.safeAreaLayoutGuide
            NSLayoutConstraint.activate([
                stack.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
                stack.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
                stack.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
                stack.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -20.0),
            ])
    
        }
        
        override func viewDidLayoutSubviews() {
            super.viewDidLayoutSubviews()
    
            // image views are in a stack view,
            //  so we need to force their layouts
            //  before asking for their frames
            photoPreview1.setNeedsLayout()
            photoPreview1.layoutIfNeeded()
            photoPreview2.setNeedsLayout()
            photoPreview2.layoutIfNeeded()
            
            guard let img1 = UIImage(named: "image4kx4k") else { return }
            guard let img2 = UIImage(named: "image500x500") else { return }
            
            let img1r = img1.withRoundedCorners(radius: 25, targetSize: photoPreview1.frame.size)
            let img2r = img2.withRoundedCorners(radius: 25, targetSize: photoPreview2.frame.size)
    
            photoPreview1.image = img1r
            photoPreview2.image = img2r
    
        }
        
    }
    

    使用此4kx4k 图像(原始来源:https://images.wallpaperscraft.com/image/single/night_city_aerial_view_city_lights_130879_4000x4000.jpg):

    还有这张500x500的图片(原始来源:https://www.digitalphotopix.com/wp-content/uploads/2011/02/blue-lake.jpg

    我们得到这个输出:

    【讨论】:

      猜你喜欢
      • 2011-06-20
      • 1970-01-01
      • 2011-12-04
      • 1970-01-01
      • 2010-09-20
      • 2010-09-17
      • 2014-10-18
      • 2012-12-17
      相关资源
      最近更新 更多