如何在swift中在UIImage上绘制/涂鸦线? [英] how to draw / doodle line on UIImage in swift?

查看:673
本文介绍了如何在swift中在UIImage上绘制/涂鸦线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我需要在UIImage中绘制/涂鸦一行,如上图所示,我看到很多教程在UIView上涂鸦线但不在UIImage中。



用户在图像上涂鸦后,我想将其保存为新图像(图像有线条) 。我怎么在Swift中做到这一点?



我只能在UIView上找到绘制线而不是在UIImage
中用于绘制UIView就像这样的youtube教程


I need to draw / doodle a line in UIImage like the picture above , I see a lot of tutorials doodle line on the UIView but not in the UIImage.

after the user doodle on the Image, I want to save it as the new image (Image that has lines). how do I do that in Swift?

i just can find draw line on UIView not in the UIImage the for drawing on UIView is like this one in this youtube tutorial http://youtube.com/watch?v=gbFHqHHApC4 , I change it to inherit DrawView to UIImageView

   struct  Stroke {
    let startPoint : CGPoint
    let endPoint : CGPoint
    let strokeColor : CGColor
}


class DrawView : UIImageView {

    var isDrawing = false
    var lastPoint : CGPoint!
    var strokeColor : CGColor! = UIColor.black.cgColor
    var strokes = [Stroke]()


    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        guard !isDrawing else { return }
        isDrawing = true

        guard let touch = touches.first else {return}
        let currentPoint = touch.location(in: self)
        lastPoint = currentPoint
        print(currentPoint)


    }



    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

        guard isDrawing else { return}

        guard let touch = touches.first else {return}
        let currentPoint = touch.location(in: self)
        let stroke = Stroke(startPoint: lastPoint, endPoint: currentPoint, strokeColor: strokeColor)
        strokes.append(stroke)
        lastPoint = currentPoint

        setNeedsDisplay()


        print(currentPoint)
    }




    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

        guard isDrawing else { return}
        isDrawing = false


        guard let touch = touches.first else {return}

        let currentPoint = touch.location(in: self)
        let stroke = Stroke(startPoint: lastPoint, endPoint: currentPoint, strokeColor: strokeColor)
        strokes.append(stroke)

        setNeedsDisplay()

        lastPoint = nil
        print(currentPoint)

    }


    override func draw(_ rect: CGRect) {

        let context = UIGraphicsGetCurrentContext()
        context?.setLineWidth(5)
        context?.setLineCap(.round)

        for stroke in strokes {
            context?.beginPath()

            context?.move(to: stroke.startPoint)
            context?.addLine(to: stroke.endPoint)

            context?.setStrokeColor(stroke.strokeColor)
            context?.strokePath()
        }

    }


    func erase() {
        strokes = []
        strokeColor = UIColor.black.cgColor
        setNeedsDisplay()
    }






}

I have assigned the UIImage in storyboard to use custom class "DrawView" like my code above, but I don't know why the lines doesn't appear on my UIImage

解决方案

Details

Xcode 9.3, Swift 4.1

Solution

// https://stackoverflow.com/a/41009006/4488252
class DrawingImageView: UIImageView {
    var path = UIBezierPath()
    var previousTouchPoint = CGPoint.zero
    var shapeLayer = CAShapeLayer()

    override func awakeFromNib() {
        super.awakeFromNib()
        setupView()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func setupView(){
        self.layer.addSublayer(shapeLayer)
        self.shapeLayer.lineWidth = 4
        self.shapeLayer.strokeColor = UIColor.white.cgColor
        self.isUserInteractionEnabled = true
    }


    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        if let location = touches.first?.location(in: self){
            previousTouchPoint = location
        }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesMoved(touches, with: event)

        if let location = touches.first?.location(in: self){
            path.move(to: location)
            path.addLine(to: previousTouchPoint)
            previousTouchPoint = location
            shapeLayer.path = path.cgPath
        }
    }
}

// https://stackoverflow.com/a/40953026/4488252
extension UIView {

    var screenShot: UIImage?  {

        let scale = UIScreen.main.scale
        UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);
        if let context = UIGraphicsGetCurrentContext() {
            layer.render(in: context)
            let screenshot = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return screenshot
        }

        return nil
    }
}

Usage

  1. Add DrawingImageView to your root (parent) view (drawing by touch will be enabled automatically)
  2. To save UIImage use drawingImageView.screenShot

Full sample

Do not forget to add the solution code here

import UIKit

class ViewController: UIViewController {

    fileprivate weak var savedImageView: UIImageView!
    fileprivate weak var drawingImageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let drawingImageView = addImageView(image: UIImage(named: "swift")) as DrawingImageView
        drawingImageView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        drawingImageView.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height/3).isActive = true
        self.drawingImageView = drawingImageView

        let button = UIButton()
        button.setTitle("Save Image", for: .normal)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setTitleColor(.blue, for: .normal)
        view.addSubview(button)
        button.topAnchor.constraint(equalTo:drawingImageView.bottomAnchor, constant: 60).isActive = true
        button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        button.heightAnchor.constraint(equalToConstant: 44).isActive = true
        button.addTarget(self, action: #selector(saveImageButtonTouchUpInside), for: .touchUpInside)

        let savedImageView = addImageView()
        savedImageView.topAnchor.constraint(equalTo: button.bottomAnchor, constant: 60).isActive = true
        savedImageView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        self.savedImageView = savedImageView
    }

    private func addImageView<T: UIImageView>(image: UIImage? = nil) -> T {
        let imageView = T(frame: .zero)
        imageView.contentMode = .scaleAspectFit
        imageView.image = image
        view.addSubview(imageView)

        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true

        return imageView
    }

    @objc func saveImageButtonTouchUpInside(sender: UIButton) {
        savedImageView.image = drawingImageView.screenShot
    }
}

Results

这篇关于如何在swift中在UIImage上绘制/涂鸦线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆