Search code examples
swiftmacosuikitcore-graphics

MacOS: Add a text overlay to an image in Swift


I've written a small extension for UIImage, which adds a text to an image:

extension UIImage {

    func addTextToImage(textToAdd: String) -> UIImage {
        let textColor = UIColor.white
        let textFont = UIFont(name: "Snell Roundhand", size: 40)!
        let scale = UIScreen.main.scale
        UIGraphicsBeginImageContextWithOptions(self.size, false, scale)

        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.alignment = NSTextAlignment.center

        var textFontAttributes = [
            NSAttributedString.Key.font: textFont,
            NSAttributedString.Key.foregroundColor: textColor,
            NSAttributedString.Key.paragraphStyle: paragraphStyle
            ] as [NSAttributedString.Key : Any]


        self.draw(in: CGRect(origin: CGPoint.zero, size: self.size))
        let textFrame = CGPoint(x: self.size.width/4, y: self.size.height/4)
        let rect = CGRect(origin: textFrame, size: CGSize(width: self.size.width/2, height: self.size.height/2) )
        text.draw(in: rect, withAttributes: textFontAttributes)

        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage!
    }
}

The result should look like this: enter image description here

Now I want to do the same thing for NSImage to run on MacOS.

Any ideas how to do this?

All similar questions on Stackoverflow are either very old, unanswered or in Objective C


Solution

  • Found a solution:

    extension NSImage {
    
        func addTextToImage(drawText text: String) -> NSImage {
    
            let targetImage = NSImage(size: self.size, flipped: false) { (dstRect: CGRect) -> Bool in
    
                self.draw(in: dstRect)
                let textColor = NSColor.white
                let textFont = NSFont(name: "Snell Roundhand", size: 36)! //Helvetica Bold
                let paragraphStyle = NSMutableParagraphStyle()
                paragraphStyle.alignment = NSTextAlignment.center
    
                var textFontAttributes = [
                    NSAttributedString.Key.font: textFont,
                    NSAttributedString.Key.foregroundColor: textColor,
                    ] as [NSAttributedString.Key : Any]
    
                let textOrigin = CGPoint(x: self.size.height/3, y: -self.size.width/4)
                let rect = CGRect(origin: textOrigin, size: self.size)
                text.draw(in: rect, withAttributes: textFontAttributes)
                return true
            }
            return targetImage
        }
    }