iOS图片添加白色橡皮擦
2021-09-30 本文已影响0人
ufogxl
封装一个图片橡皮擦,这里使用手势识别来进行绘制操作
class eraseView:UIImageView{
var imageRect:CGRect = .zero
var lineWidth:CGFloat = 1 // 线的粗细
var layerArray:NSMutableArray = NSMutableArray() //保存当前的画线
var redoLayerArray:NSMutableArray = NSMutableArray()//可以向前复原
}
为了防止手势超出边界,需要将自身比例修改为与图片相同:
var originImage:UIImage? = nil{
didSet{
guard let img = originImage else { return }
let superSize = self.superview!.frame.size
let imageSize = img.size
if superSize.width / superSize.height > imageSize.width / imageSize.height{
imageRect = CGRect(x: 0, y: 0, width: superSize.height * imageSize.width / imageSize.height, height: superSize.height)
imageRect.origin.x = (superSize.width - imageRect.width) / 2
}else{
imageRect = CGRect(x: 0, y: 0, width: superSize.width, height: superSize.width * imageSize.height / imageSize.width)
imageRect.origin.y = (superSize.height - imageRect.height) / 2
}
self.frame = imageRect
self.image = img
}
自定义一个Layer用来绘制
class LY_DrawLayer:CAShapeLayer{
var bPath:UIBezierPath
override init() {
bPath = UIBezierPath()
bPath.lineJoinStyle = .round
bPath.lineCapStyle = .round
super.init()
self.fillColor = UIColor.clear.cgColor
}
override init(layer: Any) {
bPath = UIBezierPath()
super.init(layer: layer)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
初始化,添加手势识别,并打开交互手势
override init(frame:CGRect) {
super.init(frame: frame)
let gesture = UIPanGestureRecognizer(target: self, action: #selector(drawLine))
self.addGestureRecognizer(gesture)
self.isUserInteractionEnabled = true
self.contentMode = .scaleAspectFit
self.clipsToBounds = true
self.backgroundColor = .clear
}
@objc func drawLine(gesture:UIPanGestureRecognizer) {
let currentPoint = gesture.location(in: self)
if gesture.state == .began {
let layer = LY_DrawLayer()
layer.frame = self.bounds
layer.strokeColor = UIColor.color(hexString: "#FF00FF", alpha: 0.2).cgColor
layer.lineWidth = lineWidth
layer.bPath.move(to: currentPoint)
self.layer.addSublayer(layer)
layerArray.add(layer)
isDraw = true
}
let topLayer = layerArray.lastObject as? LY_DrawLayer
topLayer?.bPath.addLine(to: currentPoint)
if gesture.state == .ended {
topLayer?.strokeColor = UIColor.white.cgColor
redoLayerArray.removeAllObjects()
isDraw = false
}
topLayer?.path = topLayer?.bPath.cgPath
}
func undo(){
redoLayerArray.push(object: layerArray.pop())
(redoLayerArray.lastObject as? CALayer)?.removeFromSuperlayer()
}
func redo(){
layerArray.push(object: redoLayerArray.pop())
if let layer = layerArray.lastObject as? CALayer{
self.layer.addSublayer(layer)
}
}
最后实现一下生成图片的方法,这里要确保和原图大小一致:
func toImage() -> UIImage{
var result:UIImage? = nil
if layerArray.count > 0{
UIGraphicsBeginImageContextWithOptions(image.size, false, screenScale)
image.draw(in: CGRect(origin: .zero, size: image.size))
image = nil
drawHierarchy(in: CGRect(origin: .zero, size: image.size), afterScreenUpdates: true)
result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
}
return result ?? originImage
}