从代码(PaintCode)绘制的视图是像素化的,缩放时非常像素化
Views drawn from code (PaintCode) are pixelated, very pixelated when scaled
我正在构建一个应用程序,它将使用代码(PaintCode 的输出)绘制的视图叠加到照片上。我添加了手势识别器来旋转和缩放用代码绘制的视图。
顶部绘制的视图有一些轻微的像素化。如果我进行任何旋转或将图像放大(甚至一点点),就会有更多的像素化。
这是图像的比较:
无旋转或缩放:
少量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 之类的东西,也没有区别。
这是我用于 scale/rotation 手势识别器的代码:
@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) 中尝试过使画布变得非常大,但没有区别,所以我认为这与此无关。
我怎样才能 draw/export 这些视图不被像素化?
编辑:这是一些绘图代码的样子...
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:)
方法。
在绘制的视图上设置 contentsScale
很重要,即使该视图未缩放(但其某些父视图已缩放)。一个常见的解决方案是在缩放视图的所有子图层上递归设置contentsScale
。
– PaintCode 支持
我正在构建一个应用程序,它将使用代码(PaintCode 的输出)绘制的视图叠加到照片上。我添加了手势识别器来旋转和缩放用代码绘制的视图。
顶部绘制的视图有一些轻微的像素化。如果我进行任何旋转或将图像放大(甚至一点点),就会有更多的像素化。
这是图像的比较:
无旋转或缩放:
少量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 之类的东西,也没有区别。
这是我用于 scale/rotation 手势识别器的代码:
@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) 中尝试过使画布变得非常大,但没有区别,所以我认为这与此无关。
我怎样才能 draw/export 这些视图不被像素化?
编辑:这是一些绘图代码的样子...
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:)
方法。
在绘制的视图上设置 contentsScale
很重要,即使该视图未缩放(但其某些父视图已缩放)。一个常见的解决方案是在缩放视图的所有子图层上递归设置contentsScale
。
– PaintCode 支持