CoreGraphicsで消しゴムツールを作成することには、多くの質問があります。私は "pixilated"と一致するものを見つけることができません。スウィフト - 私の消しゴムツールはなぜピクセル化されますか
ここに状況があります。私は簡単な描画プロジェクトで遊んでいます。ペンツールはうまく動作します。消しゴムツールは恐ろしいようにピクセル化されています。ここで私が何を意味するかのスクリーンショットだ:
// DrawingView
//
//
// Created by David DelMonte on 12/9/16.
// Copyright © 2016 David DelMonte. All rights reserved.
//
import UIKit
public protocol DrawingViewDelegate {
func didBeginDrawing(view: DrawingView)
func isDrawing(view: DrawingView)
func didFinishDrawing(view: DrawingView)
func didCancelDrawing(view: DrawingView)
}
open class DrawingView: UIView {
//initial settings
public var lineColor: UIColor = UIColor.black
public var lineWidth: CGFloat = 10.0
public var lineOpacity: CGFloat = 1.0
//public var lineBlendMode: CGBlendMode = .normal
//used for zoom actions
public var drawingEnabled: Bool = true
public var delegate: DrawingViewDelegate?
private var currentPoint: CGPoint = CGPoint()
private var previousPoint: CGPoint = CGPoint()
private var previousPreviousPoint: CGPoint = CGPoint()
private var pathArray: [Line] = []
private var redoArray: [Line] = []
var toolType: Int = 0
let π = CGFloat(M_PI)
private let forceSensitivity: CGFloat = 4.0
private struct Line {
var path: CGMutablePath
var color: UIColor
var width: CGFloat
var opacity: CGFloat
//var blendMode: CGBlendMode
init(path : CGMutablePath, color: UIColor, width: CGFloat, opacity: CGFloat) {
self.path = path
self.color = color
self.width = width
self.opacity = opacity
//self.blendMode = blendMode
}
}
override public init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.clear
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.backgroundColor = UIColor.clear
}
override open func draw(_ rect: CGRect) {
let context : CGContext = UIGraphicsGetCurrentContext()!
for line in pathArray {
context.setLineWidth(line.width)
context.setAlpha(line.opacity)
context.setLineCap(.round)
switch toolType {
case 0: //pen
context.setStrokeColor(line.color.cgColor)
context.addPath(line.path)
context.setBlendMode(.normal)
break
case 1: //eraser
context.setStrokeColor(UIColor.clear.cgColor)
context.addPath(line.path)
context.setBlendMode(.clear)
break
case 3: //multiply
context.setStrokeColor(line.color.cgColor)
context.addPath(line.path)
context.setBlendMode(.multiply)
break
default:
break
}
context.beginTransparencyLayer(auxiliaryInfo: nil)
context.strokePath()
context.endTransparencyLayer()
}
}
override open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard drawingEnabled == true else {
return
}
self.delegate?.didBeginDrawing(view: self)
if let touch = touches.first as UITouch! {
//setTouchPoints(touch, view: self)
previousPoint = touch.previousLocation(in: self)
previousPreviousPoint = touch.previousLocation(in: self)
currentPoint = touch.location(in: self)
let newLine = Line(path: CGMutablePath(), color: self.lineColor, width: self.lineWidth, opacity: self.lineOpacity)
newLine.path.addPath(createNewPath())
pathArray.append(newLine)
}
}
override open func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard drawingEnabled == true else {
return
}
self.delegate?.isDrawing(view: self)
if let touch = touches.first as UITouch! {
//updateTouchPoints(touch, view: self)
previousPreviousPoint = previousPoint
previousPoint = touch.previousLocation(in: self)
currentPoint = touch.location(in: self)
let newLine = createNewPath()
if let currentPath = pathArray.last {
currentPath.path.addPath(newLine)
}
}
}
override open func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
guard drawingEnabled == true else {
return
}
}
override open func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
guard drawingEnabled == true else {
return
}
}
public func canUndo() -> Bool {
if pathArray.count > 0 {return true}
return false
}
public func canRedo() -> Bool {
return redoArray.count > 0
}
public func undo() {
if pathArray.count > 0 {
redoArray.append(pathArray.last!)
pathArray.removeLast()
}
setNeedsDisplay()
}
public func redo() {
if redoArray.count > 0 {
pathArray.append(redoArray.last!)
redoArray.removeLast()
}
setNeedsDisplay()
}
public func clearCanvas() {
pathArray = []
setNeedsDisplay()
}
private func createNewPath() -> CGMutablePath {
//print(#function)
let midPoints = getMidPoints()
let subPath = createSubPath(midPoints.0, mid2: midPoints.1)
let newPath = addSubPathToPath(subPath)
return newPath
}
private func calculateMidPoint(_ p1 : CGPoint, p2 : CGPoint) -> CGPoint {
//print(#function)
return CGPoint(x: (p1.x + p2.x) * 0.5, y: (p1.y + p2.y) * 0.5);
}
private func getMidPoints() -> (CGPoint, CGPoint) {
//print(#function)
let mid1 : CGPoint = calculateMidPoint(previousPoint, p2: previousPreviousPoint)
let mid2 : CGPoint = calculateMidPoint(currentPoint, p2: previousPoint)
return (mid1, mid2)
}
private func createSubPath(_ mid1: CGPoint, mid2: CGPoint) -> CGMutablePath {
//print(#function)
let subpath : CGMutablePath = CGMutablePath()
subpath.move(to: CGPoint(x: mid1.x, y: mid1.y))
subpath.addQuadCurve(to: CGPoint(x: mid2.x, y: mid2.y), control: CGPoint(x: previousPoint.x, y: previousPoint.y))
return subpath
}
private func addSubPathToPath(_ subpath: CGMutablePath) -> CGMutablePath {
//print(#function)
let bounds : CGRect = subpath.boundingBox
let drawBox : CGRect = bounds.insetBy(dx: -0.54 * lineWidth, dy: -0.54 * lineWidth)
self.setNeedsDisplay(drawBox)
return subpath
}
}
UPDATE:
私は、各消しゴムのタッチがあることがわかり
ここで描画コードは、私が(更新)使用しています平方。より詳細に示すために、第2の画像をご覧ください。
Pranal Jaiswalにより示唆されるように、私はその後、いくつかのコードを書き直しました:
override open func draw(_ rect: CGRect) {
print(#function)
let context : CGContext = UIGraphicsGetCurrentContext()!
if isEraserSelected {
for line in undoArray {
//context.beginTransparencyLayer(auxiliaryInfo: nil)
context.setLineWidth(line.width)
context.addPath(line.path)
context.setStrokeColor(UIColor.clear.cgColor)
context.setBlendMode(.clear)
context.setAlpha(line.opacity)
context.setLineCap(.round)
context.strokePath()
}
} else {
for line in undoArray {
context.setLineWidth(line.width)
context.setLineCap(.round)
context.addPath(line.path)
context.setStrokeColor(line.color.cgColor)
context.setBlendMode(.normal)
context.setAlpha(line.opacity)
context.strokePath()
}
}
}
I'm still getting the same result. I'd appreciate any more help.
uはウル描画クラスのコード全体を投稿することができますか?私はそのような問題をよりよく理解することができます... –
もう一度見ていただきありがとうございます。私は完全な描画クラスを今追加しました。注意してください、私は私の元に戻す/やり直し機能で使用するためにポイントを格納するために配列を使用しています –
なぜ下の投票をしてください? –