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
}
上一篇 下一篇

猜你喜欢

热点阅读