从代码(PaintCode)中提取的视图是像素化的,在缩放

时间:2017-03-23 14:02:48

标签: ios swift paint-code

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

在顶部绘制的视图中有一些温和的像素化。如果我进行任何旋转或缩放图像(甚至稍微一点),则会出现更多的像素化。

以下是图片的比较:

无旋转或缩放: No rotation or scaling

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

这是我用来输出合成视图的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)中使画布非常大,并且没有区别,所以我认为它与此无关。

如何绘制/导出这些视图以使它们不像素化?

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

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))

1 个答案:

答案 0 :(得分:1)

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

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

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

在该绘制的视图上设置contentsScale非常重要,即使该视图未缩放(但其某些父视图也是如此)。一个常见的解决方案是在缩放视图的所有子图层上递归设置contentsScale

- PaintCode支持