ios - 从代码(PaintCode)绘制的 View 是像素化的,缩放时非常像素化

标签 ios swift paintcode

我正在构建一个应用程序,它将使用代码(PaintCode 的输出)绘制的 View 叠加到照片上。我添加了手势识别器来旋转和缩放用代码绘制的 View 。

在顶部绘制的 View 上有一些轻微的像素化。如果我对图像进行任何旋转或将图像放大(哪怕是一点点),就会出现更多的像素化。

这是图像的比较:

无旋转或缩放: No rotation or scaling

少量旋转/缩放: A small amount of rotation/scaling

这是我用来输出复合 View 的 UIView 扩展:

extension UIView {

    func printViewToImage() -> UIImage {
        let format = UIGraphicsImageRendererFormat()
        format.scale = 2.0

        let renderer = UIGraphicsImageRenderer(bounds: self.bounds, format: format)
        return renderer.image { rendererContext in
            self.drawHierarchy(in: self.bounds, afterScreenUpdates: true)
        }
    }
}

即使我将比例设置为 4.0 之类的东西,也没有区别。

这是我用于缩放/旋转手势识别器的代码:

@IBAction func handlePinch(recognizer: UIPinchGestureRecognizer) {
    guard let view = recognizer.view else {
        return
    }

    view.transform = view.transform.scaledBy(x: recognizer.scale, y: recognizer.scale)
    recognizer.scale = 1
}

@IBAction func handleRotate(recognizer: UIRotationGestureRecognizer) {
    guard let view = recognizer.view else {
        return
    }

    view.transform = view.transform.rotated(by: recognizer.rotation)
    recognizer.rotation = 0
}

我已经尝试在 PaintCode (3000x3000) 中使 Canvas 变得非常大,但没有区别,所以我认为这与此无关。

如何绘制/导出这些 View ,以免它们像素化?

编辑:下面是一些绘图代码的样子...

public dynamic class func drawCelebrateDiversity(frame targetFrame: CGRect = CGRect(x: 0, y: 0, width: 3000, height: 3000), resizing: ResizingBehavior = .aspectFit, color: UIColor = UIColor(red: 1.000, green: 1.000, blue: 1.000, alpha: 1.000)) {
    //// General Declarations
    let context = UIGraphicsGetCurrentContext()!

    //// Resize to Target Frame
    context.saveGState()
    let resizedFrame: CGRect = resizing.apply(rect: CGRect(x: 0, y: 0, width: 3000, height: 3000), target: targetFrame)
    context.translateBy(x: resizedFrame.minX, y: resizedFrame.minY)
    context.scaleBy(x: resizedFrame.width / 3000, y: resizedFrame.height / 3000)


    //// Bezier 13 Drawing
    let bezier13Path = UIBezierPath()
    bezier13Path.move(to: CGPoint(x: 2915.18, y: 2146.51))
    bezier13Path.addCurve(to: CGPoint(x: 2925.95, y: 2152.38), controlPoint1: CGPoint(x: 2919.93, y: 2147.45), controlPoint2: CGPoint(x: 2924.05, y: 2147.91))

最佳答案

当缩放 UIView(或自定义 CALayer)时,您应该设置它们的 contentsScale 以匹配它们的内容所需的密度。 UIViews 将它们的层 contentsScale 设置为屏幕比例(在视网膜上为 2),您需要将其乘以通过变换所做的额外比例。

view.layer.contentsScale = UIScreen.main.scale * gesture.scale;

即使绘图代码与分辨率无关,屏幕上的所有内容有时也必须转换为位图。 UIView 分配大小为 bounds.size * contentsScale 的位图,然后调用 -drawRect:/draw(_ rect:) 方法。

在绘制的 View 上设置 contentsScale 很重要,即使该 View 未缩放(但它的某些父 View 已缩放)。一个常见的解决方案是在缩放 View 的所有子层上递归设置 contentsScale

– PaintCode 支持

关于ios - 从代码(PaintCode)绘制的 View 是像素化的,缩放时非常像素化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42978322/

相关文章:

ios - 2 型蹦床用完

javascript - iOS亚麻布背景CSS?

ios - Firebase 子查询排序无法正常工作

ios - 当 View 出现时以编程方式定义 UILabel 的大小

ios - 图标 Assets 与图标代码

ios - PaintCode Canvas 的最佳宽度和高度是多少?

c# - Xamarin 中的可移植类库在 iOS 模拟器上工作但不在设备上工作

ios - 有没有办法将 UI 组件(例如 UIButtons)拆分为单独的 .swift 文件,然后在另一个 .swift 文件的 ViewController 类中使用它们

swift - 在 Swift 中使用 "/"的 Base64Encoding 结果字符串

ios - 将自定义类添加到 UITableView 中的 UIView