Search code examples
swiftmacosnsimage

textToImage shows different results in macOS


I use this code to place a text in an image:

extension NSImage {
     
     //https://stackoverflow.com/questions/54450429/macos-add-a-text-overlay-to-an-image-in-swift
     
     func textToImage(naam: String, slogan: String) -> NSImage {
          
         let targetImage = NSImage(size: self.size, flipped: false) { (dstRect: CGRect) -> Bool in

             let naamColor = NSColor.black

             let naamFont = NSFont(name: "Montserrat-SemiBold", size: 110)!
                         
             let paragraph = NSMutableParagraphStyle()
             paragraph.alignment = .center
             
             let naamFontAttributes = [NSAttributedString.Key.font: naamFont, .paragraphStyle: paragraph, NSAttributedString.Key.foregroundColor: naamColor] as [NSAttributedString.Key : Any]

             let naamString = NSAttributedString(string: naam, attributes: naamFontAttributes)

             self.draw(in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))

             let rectNaam = CGRect(x: 25, y: -25, width: self.size.width-25, height: self.size.height)
             
             naamString.draw(in: rectNaam)

             return true
                
         }
                
         return targetImage
          
     }
     
}

I use it in this way:

let image = loadImage(named: "eigenradiostation.png")
                
let imageWithText = image.textToImage(naam: radiostationGeselecteerd[0], slogan: radiostationGeselecteerd[1])

//downsample zodat widget niet > 16 MB komt
imageWithText.size = CGSize(width: 100, height: 100)

let imageData = imageWithText.tiffRepresentation!
                                    
recentAfgespeeldeRadiostationsTegels.insert(imageData, at:0)

I don't understand why the result differs from time to time. It looks that sometimes the imageWithText.size is executed first and then image.textToImage somehow?!

enter image description here enter image description here


Solution

  • I changed the usage from 1st adding text and 2nd resizing to 1st resizing and 2nd adding text. And that works somehow:

    let image = loadImage(named: "eigenradiostation.png")
      
    //downsample zodat widget niet > 16 MB komt
    image.size = CGSize(width: 100, height: 100)
                  
    let imageWithText = image.textToImage(naam: radiostationGeselecteerd[0], slogan: radiostationGeselecteerd[1])
    
    let imageData = imageWithText.tiffRepresentation!
                                        
    recentAfgespeeldeRadiostationsTegels.insert(imageData, at:0)
    

    I changed the font size and margins in the extension:

    extension NSImage {
         
         //https://stackoverflow.com/questions/54450429/macos-add-a-text-overlay-to-an-image-in-swift
         
         func textToImage(naam: String, slogan: String) -> NSImage {
              
             let targetImage = NSImage(size: self.size, flipped: false) { (dstRect: CGRect) -> Bool in
    
                 let naamColor = NSColor.black
    
                 let naamFont = NSFont(name: "Montserrat-SemiBold", size: 12)!
                             
                 let paragraph = NSMutableParagraphStyle()
                 paragraph.alignment = .center
                 
                 let naamFontAttributes = [NSAttributedString.Key.font: naamFont, .paragraphStyle: paragraph, NSAttributedString.Key.foregroundColor: naamColor] as [NSAttributedString.Key : Any]
    
                 let naamString = NSAttributedString(string: naam, attributes: naamFontAttributes)
    
                 self.draw(in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
    
                 let rectNaam = CGRect(x: 5, y: -5, width: self.size.width-25, height: self.size.height)
                 
                 naamString.draw(in: rectNaam)
    
                 return true
                    
             }
                    
             return targetImage
              
         }
         
    }