【问题标题】:Image size error while rendering UIView to UIImage将 UIView 渲染为 UIImage 时出现图像大小错误
【发布时间】:2021-06-01 14:35:59
【问题描述】:

我想通过自定义设计将两张图片转换为一张图片。 预期的图像是我的 UICollectionViewCell 的快照,实际上不是 UIImage。 我从自定义 UICVCell.swift 文件中复制了布局代码,并尝试将视图渲染到 UIImage 中,但结果图像如下所示。

我在 SOF 中搜索了很多问题,但大部分都是关于“如何将 UIView 渲染为 UIImage”。 我也尝试过绘图,但结果同样混乱。

谁能告诉我有什么问题? 非常感谢您的帮助,这是我在 SOF 中的第一个问题。 我可能会在一两分钟内哭泣,真的......

类视图控制器:UIViewController {

private var imageView: UIImageView = {
    let iv = UIImageView()
    iv.contentMode = .scaleAspectFit
    iv.clipsToBounds = true

    return iv
}()

func createBubbleImage(images: [UIImage?]) -> UIImage? {
    switch images.count {
    case 1:
        return images[0]
    case 2:
        let newView = UIView(frame: .init(x: 0, y: 0, width: 300, height: 300))
        let size = newView.frame.width

        let iv0 = UIImageView(image: images[0])
        iv0.contentMode = .scaleAspectFit
        iv0.clipsToBounds = true

        let iv1 = UIImageView(image: images[1])
        iv1.contentMode = .scaleAspectFit
        iv1.clipsToBounds = true

        newView.addSubview(iv0)
        iv0.anchor(top: newView.topAnchor, left: newView.leftAnchor, paddingTop: size * 0.04, paddingLeft: size * 0.04, width: size * 0.56, height: size * 0.56)
        newView.addSubview(iv1)
        iv1.anchor(bottom: newView.bottomAnchor, right: newView.rightAnchor, paddingBottom: size * 0.04, paddingRight: size * 0.04, width: size * 0.56, height: size * 0.56)
        
        iv0.layer.cornerRadius = size * 0.28
        iv1.layer.cornerRadius = size * 0.28
        
        let renderer = UIGraphicsImageRenderer(bounds: newView.bounds)
        return renderer.image { ctx in
            newView.layer.render(in: ctx.cgContext)
        }
        
    default:
        return UIImage(named: "logo")
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    
    view.backgroundColor = .white
    
    view.addSubview(imageView)
    imageView.center(inView: view)
    imageView.setDimensions(width: 300, height: 300)

    imageView.image = createBubbleImage(images: [UIImage(named: "0"), UIImage(named: "1")])
}

}

Expected Image Result Image

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    执行以下操作:

    1. 删除具有anchor 方法的代码行。
    2. UIImageView(frame: ...) 启动iv0iv1
    3. 添加iv0.image = images[0]iv1.image = images[1]

    我还增加了一点半径,因为在我的测试设备中,图像不是完全圆形的。

    代码应如下所示:

    func createBubbleImage(images: [UIImage?]) -> UIImage? {
        switch images.count {
        case 1:
            return images[0]
        case 2:
            let newView = UIView(frame: .init(x: 0, y: 0, width: 300, height: 300))
            let size = newView.frame.width
    
            let iv0 = UIImageView(frame: .init(x: 0, y: 0, width: 200, height: 200))
            iv0.image = images[0]
            iv0.contentMode = .scaleAspectFit
            iv0.clipsToBounds = true
    
            let iv1 = UIImageView(frame: .init(x: 100, y: 100, width: 200, height: 200))
            iv1.image = images[1]
            iv1.contentMode = .scaleAspectFit
            iv1.clipsToBounds = true
    
            newView.addSubview(iv0)
            newView.addSubview(iv1)
    
            iv0.layer.cornerRadius = size * 0.35
            iv1.layer.cornerRadius = size * 0.35
    
            let renderer = UIGraphicsImageRenderer(bounds: newView.bounds)
            return renderer.image { ctx in
                newView.layer.render(in: ctx.cgContext)
            }
    
        default:
            return UIImage(named: "logo")
        }
    }
    

    有了它,结果如下:

    我必须从您的“预期图像”中截取屏幕截图,这就是图像看起来像放大的原因。您可以使用UIImageView(frame: ...) 部分来根据需要调整两个图像(我玩得不够避免在边缘切割,但可以通过正确的措施)。

    备注:UIImageView 框架中的xy 值分别是从newView 的左上角到UIImageView 的左上角的水平和垂直距离。

    【讨论】:

    • 非常感谢。我真的非常感谢你的回答。它完美地工作!不过,可能是什么问题?由于我设置相对布局并使用绝对布局时它不起作用,是因为在设置布局之前触发了渲染?
    • 我很高兴它成功了 :)。我认为问题在于图像的大小。在您的方法中,您分配图像,然后在 .anchor(...) 方法中调整它的大小。也许这种方法只调整框架而不是实际图像(我真的不知道)。在我的回答中,您首先设置框架,然后设置图像(在这种情况下,图像适合框架大小)。
    • 哦...这很有道理。谢谢回复,真的。祝你今天过得愉快! :)
    猜你喜欢
    • 2012-10-20
    • 2014-06-21
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 2019-11-02
    • 2020-07-30
    • 1970-01-01
    • 2016-12-06
    相关资源
    最近更新 更多