绘制完美的圆角线,Swift
Drawing perfect rounding lines, Swift
我正在开发一个绘图应用程序原型,我想要实现的是完美的圆角线。我已经通过曲线实现了绘图,但我的线条看起来还是有点像素化。
这是我的结果:
这是我想要实现的目标:
class ViewController: UIViewController {
private var currentPoint: CGPoint?
private var previousPoint1: CGPoint?
private var previousPoint2: CGPoint?
private var lineColor = UIColor.black
private var lineWidth = CGFloat(10)
private var lineAlpha = CGFloat(1)
@IBOutlet private weak var imageView: UIImageView!
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
previousPoint1 = touch.previousLocation(in: self.view)
currentPoint = touch.location(in: self.view)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
previousPoint2 = previousPoint1
previousPoint1 = touch.previousLocation(in: self.view)
currentPoint = touch.location(in: self.view)
let mid1 = middlePoint(previousPoint1!, previousPoint2: previousPoint2!)
let mid2 = middlePoint(currentPoint!, previousPoint2: previousPoint1!)
draw(move: CGPoint(x: mid1.x, y: mid1.y), to: CGPoint(x: mid2.x, y: mid2.y), control: CGPoint(x: previousPoint1!.x, y: previousPoint1!.y))
}
public override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
touchesMoved(touches, with: event)
}
private func middlePoint(_ previousPoint1: CGPoint, previousPoint2: CGPoint) -> CGPoint {
return CGPoint(x: (previousPoint1.x + previousPoint2.x) * 0.5, y: (previousPoint1.y + previousPoint2.y) * 0.5)
}
func draw(move: CGPoint, to: CGPoint, control: CGPoint) {
UIGraphicsBeginImageContext(view.frame.size)
guard let ctx = UIGraphicsGetCurrentContext() else { return }
imageView.image?.draw(in: view.bounds)
ctx.move(to: move)
ctx.addQuadCurve(to: to, control: control)
ctx.setLineCap(.round)
ctx.setLineJoin(.round)
ctx.setLineWidth(lineWidth)
ctx.setStrokeColor(lineColor.cgColor)
ctx.setBlendMode(.normal)
ctx.setAlpha(lineAlpha)
ctx.strokePath()
let finalImage = UIGraphicsGetImageFromCurrentImageContext()
imageView.image = finalImage
UIGraphicsEndImageContext()
}
}
P.S。我想通过上下文绘制,而不是使用 drawRect
这里的问题是您创建的imageContext 的比例不正确。与其使用 UIGraphicsBeginImageContext 创建上下文,不如尝试使用 UIGraphicsBeginImageContextWithOptions 创建它,并将比例值设为 0。当您指定比例值为 0 时,比例因子设置为设备主屏幕的比例因子。更新后的代码片段如下所示。
func draw(move: CGPoint, to: CGPoint, control: CGPoint) {
UIGraphicsBeginImageContextWithOptions(view.frame.size, false, 0)
guard let ctx = UIGraphicsGetCurrentContext() else { return }
imageView.image?.draw(in: view.bounds)
ctx.move(to: move)
ctx.addQuadCurve(to: to, control: control)
ctx.setLineCap(.round)
ctx.setLineJoin(.round)
ctx.setLineWidth(lineWidth)
ctx.setStrokeColor(lineColor.cgColor)
ctx.setBlendMode(.normal)
ctx.setAlpha(lineAlpha)
ctx.strokePath()
let finalImage = UIGraphicsGetImageFromCurrentImageContext()
imageView.image = finalImage
UIGraphicsEndImageContext()
}
我正在开发一个绘图应用程序原型,我想要实现的是完美的圆角线。我已经通过曲线实现了绘图,但我的线条看起来还是有点像素化。
这是我的结果:
这是我想要实现的目标:
class ViewController: UIViewController {
private var currentPoint: CGPoint?
private var previousPoint1: CGPoint?
private var previousPoint2: CGPoint?
private var lineColor = UIColor.black
private var lineWidth = CGFloat(10)
private var lineAlpha = CGFloat(1)
@IBOutlet private weak var imageView: UIImageView!
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
previousPoint1 = touch.previousLocation(in: self.view)
currentPoint = touch.location(in: self.view)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
previousPoint2 = previousPoint1
previousPoint1 = touch.previousLocation(in: self.view)
currentPoint = touch.location(in: self.view)
let mid1 = middlePoint(previousPoint1!, previousPoint2: previousPoint2!)
let mid2 = middlePoint(currentPoint!, previousPoint2: previousPoint1!)
draw(move: CGPoint(x: mid1.x, y: mid1.y), to: CGPoint(x: mid2.x, y: mid2.y), control: CGPoint(x: previousPoint1!.x, y: previousPoint1!.y))
}
public override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
touchesMoved(touches, with: event)
}
private func middlePoint(_ previousPoint1: CGPoint, previousPoint2: CGPoint) -> CGPoint {
return CGPoint(x: (previousPoint1.x + previousPoint2.x) * 0.5, y: (previousPoint1.y + previousPoint2.y) * 0.5)
}
func draw(move: CGPoint, to: CGPoint, control: CGPoint) {
UIGraphicsBeginImageContext(view.frame.size)
guard let ctx = UIGraphicsGetCurrentContext() else { return }
imageView.image?.draw(in: view.bounds)
ctx.move(to: move)
ctx.addQuadCurve(to: to, control: control)
ctx.setLineCap(.round)
ctx.setLineJoin(.round)
ctx.setLineWidth(lineWidth)
ctx.setStrokeColor(lineColor.cgColor)
ctx.setBlendMode(.normal)
ctx.setAlpha(lineAlpha)
ctx.strokePath()
let finalImage = UIGraphicsGetImageFromCurrentImageContext()
imageView.image = finalImage
UIGraphicsEndImageContext()
}
}
P.S。我想通过上下文绘制,而不是使用 drawRect
这里的问题是您创建的imageContext 的比例不正确。与其使用 UIGraphicsBeginImageContext 创建上下文,不如尝试使用 UIGraphicsBeginImageContextWithOptions 创建它,并将比例值设为 0。当您指定比例值为 0 时,比例因子设置为设备主屏幕的比例因子。更新后的代码片段如下所示。
func draw(move: CGPoint, to: CGPoint, control: CGPoint) {
UIGraphicsBeginImageContextWithOptions(view.frame.size, false, 0)
guard let ctx = UIGraphicsGetCurrentContext() else { return }
imageView.image?.draw(in: view.bounds)
ctx.move(to: move)
ctx.addQuadCurve(to: to, control: control)
ctx.setLineCap(.round)
ctx.setLineJoin(.round)
ctx.setLineWidth(lineWidth)
ctx.setStrokeColor(lineColor.cgColor)
ctx.setBlendMode(.normal)
ctx.setAlpha(lineAlpha)
ctx.strokePath()
let finalImage = UIGraphicsGetImageFromCurrentImageContext()
imageView.image = finalImage
UIGraphicsEndImageContext()
}