how to draw / doodle line on UIImage in swift?

前端 未结 3 1538
再見小時候
再見小時候 2021-01-01 00:28

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

相关标签:
3条回答
  • 2021-01-01 01:05

    This may help you . Refer the link

    How do I draw on an image in Swift?

    1. Make an image graphics context. (Before iOS 10, you would do this by calling UIGraphicsBeginImageContextWithOptions. In iOS 10 there's another way, UIGraphicsImageRenderer, but you don't have to use it if you don't want to.)

    2. Draw (i.e. copy) the image into the context. (UIImage actually has draw... methods for this very purpose.)

    3. Draw your line into the context. (There are CGContext functions for this.)

    4. Extract the resulting image from the context. (For example, if you used UIGraphicsBeginImageContextWithOptions, you would use UIGraphicsGetImageFromCurrentImageContext.) Then close the context.

    0 讨论(0)
  • 2021-01-01 01:07

    You can put your UIImageView in background and UIView at top of it and then capture UIView as Image and merge it.

    Refer this to capture UIView: How to capture UIView to UIImage without loss of quality on retina display

    And then Merge it using :

    func mergeImages (forgroundImage : UIImage, backgroundImage : UIImage, size : CGSize) -> UIImage {
    
         let bottomImage = backgroundImage
         UIGraphicsBeginImageContext(size)
    
         let areaSize = CGRect(x: 0, y: 0, width: size.width, height: size.height)
         bottomImage.draw(in: areaSize)
    
         let topImage      = forgroundImage
         topImage.draw(in: areaSize, blendMode: .normal, alpha: 1.0)
    
         let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    
         UIGraphicsEndImageContext()
    
       return newImage
    }
    
    0 讨论(0)
  • 2021-01-01 01:14

    Details

    • Xcode 10.2.1 (10E1001), Swift 5

    Solution

    import UIKit
    
    // https://stackoverflow.com/a/41009006/4488252
    class DrawnImageView: UIImageView {
        private lazy var path = UIBezierPath()
        private lazy var previousTouchPoint = CGPoint.zero
        private lazy var shapeLayer = CAShapeLayer()
    
        override func awakeFromNib() {
            super.awakeFromNib()
            setupView()
        }
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            setupView()
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
    
        func setupView(){
            layer.addSublayer(shapeLayer)
            shapeLayer.lineWidth = 4
            shapeLayer.strokeColor = UIColor.white.cgColor
            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 DrawnImageView 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 drawnImageView: UIImageView?
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let drawnImageView = addImageView(image: UIImage(named: "swift")) as DrawnImageView
            drawnImageView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
            drawnImageView.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height/3).isActive = true
            self.drawnImageView = drawnImageView
    
            let button = UIButton()
            button.setTitle("Save Image", for: .normal)
            button.translatesAutoresizingMaskIntoConstraints = false
            button.setTitleColor(.blue, for: .normal)
            view.addSubview(button)
            button.topAnchor.constraint(equalTo: drawnImageView.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 = drawnImageView?.screenShot
        }
    }
    

    Results

    0 讨论(0)
提交回复
热议问题