为什么视图的快照在某些情况下会看起来太大?

问题描述 投票:0回答:1

ISSUE

当使用各种UIView扩展来拍摄UIView的快照时,结果可能看起来比它应该更大(放大的类型)。

有关问题的详情

我拍摄了2张UIViews的快照,我们可以在下面的内容中调用viewS和viewS。

  • viewA:创建快照时,视图将添加到视图层次结构中。
  • viewB:已完全定义,但在创建快照时尚未添加到视图层次结构中。然后将快照裁剪x次,并将结果添加到某些UIView以供显示。

我已经测试了3个不同的代码来获得我正在寻找的结果:一个提供了所需的快照图像,但渲染质量低;另外两个为viewA提供了更好质量的图像渲染和正确的结果,但对于viewB,虽然快照似乎有正确的矩形(我检查了rects),但是显示的图像看起来太大(好像它们被放大了两次)。

CODE

  1. 扩展#1:提供正确的结果,但图像质量低 extension UIView { func takeSnapshot() -> UIImage? { UIGraphicsBeginImageContext(self.frame.size) self.layer.render(in: UIGraphicsGetCurrentContext()!) let snapshot = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return snapshot } }
  2. 扩展#2:提供正确的图像质量,但viewB的裁剪图像显示两次太大 extension UIView { func snapshot(of rect: CGRect? = nil, afterScreenUpdates: Bool = true) -> UIImage { return UIGraphicsImageRenderer(bounds: rect ?? bounds).image { _ in drawHierarchy(in: bounds, afterScreenUpdates: true) } } }
  3. 扩展#3:同样,提供正确的图像质量,但viewB的裁剪图像显示两次太大 extension UIView { func takeScreenshot() -> UIImage { UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, UIScreen.main.scale) drawHierarchy(in: self.bounds, afterScreenUpdates: true) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() if (image != nil) { return image! } return UIImage() } }

最后但并非最不重要的是,用于从快照中提取裁剪图像的(简化)代码

    for i in (0...numberOfCroppedImages) {
        let rect    = CGRect(x: CGFloat(i) * snapshot!.size.width / CGFloat(numberOfCroppedImages), y: 0, width: snapshot!.size.width / CGFloat(numberOfCroppedImages), height:snapshot!.size.height)

        // defines the container view for the fragmented snapshots
        let view    = UIView()
        view.frame  = rect


        // defines the layer with the fragment of the snapshot
        let layer           = CALayer()
        layer.frame.size    = rect.size
        let img             = snapshot?.cgImage?.cropping(to: rect)
        layer.contents      = img
        view.layer.addSublayer(layer)
    }

到目前为止已尝试过的行动

我已经加倍检查了所有的CGRect并且我没有发现它们的任何问题:视图矩形以及快照大小似乎是预期的那个,但是,我一直有太大的渲染图像,扩展名为#2&#3对于viewB(viewA被正确渲染),而扩展#1给出了正确尺寸的图像,但质量太低而无法充分使用。

这可能是drawInHierarchy(in: afterScreenUpdates:)的问题吗?或者用let img = snapshot?.cgImage?.cropping(to: rect)转换为cgImage?

我会非常感谢任何指针!

ios swift uiview snapshot
1个回答
0
投票

我发布了一个我发现适合我的解决方案:

首先,一个快照扩展,为(无论是质量还是尺寸)呈现(无论是质量还是大小)视图是否添加到层次结构中,是否裁剪,以及:

    extension UIView {

        func takeSnapshot(of rect: CGRect? = nil, afterScreenUpdates: Bool = true) -> UIImage {
            return UIGraphicsImageRenderer(bounds: rect ?? bounds).image { (context) in
                self.layer.render(in: context.cgContext)
            }
        }

    }

然后是在视图中获取rect快照的代码的更新版本:

    let view    = UIView()
    view.frame  = rect
    let img = self.takeSnapshot(of: rect, afterScreenUpdates: true).cgImage
    view.layer.contents = img

这里的区别在于在视图中拍摄矩形的快照,而不是裁剪整个视图的快照。

我希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.