How do I draw on an image in Swift?

前端 未结 5 1505
深忆病人
深忆病人 2020-12-09 04:18

I need to be able to programmatically draw on an image, and save that image for later use. Say, draw a line on specific x and y coordinates on the image, save the image, and

5条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-12-09 04:25

    Details

    Xcode 9.1, Swift 4

    Solution

    extension UIImage

    extension UIImage {
    
        typealias RectCalculationClosure = (_ parentSize: CGSize, _ newImageSize: CGSize)->(CGRect)
    
        func with(image named: String, rectCalculation: RectCalculationClosure) -> UIImage {
            return with(image: UIImage(named: named), rectCalculation: rectCalculation)
        }
    
        func with(image: UIImage?, rectCalculation: RectCalculationClosure) -> UIImage {
    
            if let image = image {
                UIGraphicsBeginImageContext(size)
    
                draw(in: CGRect(origin: .zero, size: size))
                image.draw(in: rectCalculation(size, image.size))
    
                let newImage = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                return newImage!
            }
            return self
        }
    }
    

    extension UIImageView

        extension UIImageView {
    
        enum ImageAddingMode {
            case changeOriginalImage
            case addSubview
        }
    
        func drawOnCurrentImage(anotherImage: UIImage?, mode: ImageAddingMode, rectCalculation: UIImage.RectCalculationClosure) {
    
            guard let image = image else {
                return
            }
    
            switch mode {
            case .changeOriginalImage:
                self.image = image.with(image: anotherImage, rectCalculation: rectCalculation)
    
            case .addSubview:
                let newImageView = UIImageView(frame: rectCalculation(frame.size, image.size))
                newImageView.image = anotherImage
                addSubview(newImageView)
            }
        }
    }
    

    Images samples

    Parent Image:

    Child Image:


    Usage example 1

    func sample1(imageView: UIImageView) {
        imageView.contentMode = .scaleAspectFit
        imageView.image = UIImage(named: "parent")?.with(image: "child") { parentSize, newImageSize in
            print("parentSize = \(parentSize)")
            print("newImageSize = \(newImageSize)")
            return CGRect(x: 50, y: 50, width: 90, height: 90)
        }
    }
    

    Result 1


    Usage example 2

    func sample2(imageView: UIImageView) {
        imageView.contentMode = .scaleAspectFit
        imageView.image = UIImage(named: "parent")
        imageView.drawOnCurrentImage(anotherImage: UIImage(named: "child"), mode: .changeOriginalImage) { parentSize, newImageSize in
            print("parentSize = \(parentSize)")
            print("newImageSize = \(newImageSize)")
            let sideLength:CGFloat = 90
            let indent:CGFloat = 50
            return CGRect(x: parentSize.width-sideLength-indent, y: parentSize.height-sideLength-indent, width: sideLength, height: sideLength)
        }
    }
    

    Result 2


    Usage example 3

    func sample3(imageView: UIImageView) {
        imageView.contentMode = .scaleAspectFill
        imageView.clipsToBounds = true
        imageView.image = UIImage(named: "parent")
        imageView.drawOnCurrentImage(anotherImage: UIImage(named: "child"), mode: .addSubview) { parentSize, newImageSize in
            print("parentSize = \(parentSize)")
            print("newImageSize = \(newImageSize)")
            let sideLength:CGFloat = 90
            let indent:CGFloat = 15
            return CGRect(x: parentSize.width-sideLength-indent, y: indent, width: sideLength, height: sideLength)
        }
    }
    

    Result 3

    Full sample code

    Don't forget to add Solution code here

    import UIKit
    
    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            let imageView = UIImageView(frame: UIScreen.main.bounds)
            view.addSubview(imageView)
            sample1(imageView: imageView)
           // sample2(imageView: imageView)
           // sample3(imageView: imageView)
        }
    
        func sample1(imageView: UIImageView) {
            imageView.contentMode = .scaleAspectFit
            imageView.image = UIImage(named: "parent")?.with(image: "child") { parentSize, newImageSize in
                print("parentSize = \(parentSize)")
                print("newImageSize = \(newImageSize)")
                return CGRect(x: 50, y: 50, width: 90, height: 90)
            }
        }
    
        func sample2(imageView: UIImageView) {
            imageView.contentMode = .scaleAspectFit
            imageView.image = UIImage(named: "parent")
            imageView.drawOnCurrentImage(anotherImage: UIImage(named: "child"), mode: .changeOriginalImage) { parentSize, newImageSize in
                print("parentSize = \(parentSize)")
                print("newImageSize = \(newImageSize)")
                let sideLength:CGFloat = 90
                let indent:CGFloat = 50
                return CGRect(x: parentSize.width-sideLength-indent, y: parentSize.height-sideLength-indent, width: sideLength, height: sideLength)
            }
        }
    
        func sample3(imageView: UIImageView) {
            imageView.contentMode = .scaleAspectFill
            imageView.clipsToBounds = true
            imageView.image = UIImage(named: "parent")
            imageView.drawOnCurrentImage(anotherImage: UIImage(named: "child"), mode: .addSubview) { parentSize, newImageSize in
                print("parentSize = \(parentSize)")
                print("newImageSize = \(newImageSize)")
                let sideLength:CGFloat = 90
                let indent:CGFloat = 15
                return CGRect(x: parentSize.width-sideLength-indent, y: indent, width: sideLength, height: sideLength)
            }
        }
    }
    

提交回复
热议问题