0

I need to add some transparent padding around an NSImage.I referred this SO post Placing an NSImage on a transparent canvas in Swift

It was pointing to the the Github code https://gist.github.com/MaciejGad/11d8469b218817290ee77012edb46608 where it mentions of tweaking the resizeWhileMaintainingAspectRatioToSize method. I tried what the post has suggested but swift seems to miss the NSImage.copy method with the NSrect as parameter.So wrote the below extension method with my limited knowledge

func addPadding() -> NSImage? {
        let newSize: NSSize
        
        let widthRatio  = size.width / self.size.width
        let heightRatio = size.height / self.size.height
        
    if widthRatio > heightRatio {
            newSize = NSSize(width: floor(self.size.width * widthRatio), height: floor(self.size.height * widthRatio))
        } else {
            newSize = NSSize(width: floor(self.size.width * heightRatio), height: floor(self.size.height * heightRatio))
        }
   
          let img = NSImage(size: newSize)
          let frame = NSRect(x: 0, y: 0, width: newSize.width, height: newSize.height)

          // Set the drawing context and make sure to remove the focus before returning.
          img.lockFocus()
          defer { img.unlockFocus() }
          let representation = self.bestRepresentation(for: frame, context: nil, hints: nil)
          // Draw the new image
          if representation!.draw(in: frame) {
              return img
          }
          
          // Return nil in case something went wrong.
          return nil
    }

But this does nothing to add padding to the image.

techno
  • 6,100
  • 16
  • 86
  • 192

1 Answers1

1

You can do it with this code:

extension NSImage {
    var pixelSize: NSSize {
        if let rep = self.representations.first {
            let size = NSSize(
                width: rep.pixelsWide,
                height: rep.pixelsHigh
            )
            return size
        }
        return NSSize(width: 0, height: 0)
    }
    
    func withPadding(percent: Int) -> NSImage {
        let originalSize = self.pixelSize
        let newHeight = originalSize.height - originalSize.height * CGFloat(percent) / 100
        let newWidth = originalSize.width - originalSize.width * CGFloat(percent) / 100
        
        let sizeWithPadding = NSSize(
            width: newWidth,
            height: newHeight
        )
        
        guard let representation = NSBitmapImageRep(
            bitmapDataPlanes: nil,
            pixelsWide: Int(originalSize.width),
            pixelsHigh: Int(originalSize.height),
            bitsPerSample: 8,
            samplesPerPixel: 4,
            hasAlpha: true,
            isPlanar: false,
            colorSpaceName: .calibratedRGB,
            bytesPerRow: 0,
            bitsPerPixel: 0
        )
        else {
            return self
        }
        representation.size = originalSize
        
        NSGraphicsContext.saveGraphicsState()
        NSGraphicsContext.current = NSGraphicsContext.init(bitmapImageRep: representation)
        
        let xPoint = (originalSize.width - newWidth) / 2
        let yPoint = (originalSize.height - newHeight) / 2
        
        self.draw(
            in: NSRect(
                x: xPoint,
                y: yPoint,
                width: sizeWithPadding.width,
                height: sizeWithPadding.height
            ),
            from: .zero,
            operation: .copy,
            fraction: 1.0
        )
        NSGraphicsContext.restoreGraphicsState()
        
        let newImage = NSImage(size: originalSize)
        newImage.addRepresentation(representation)
        
        return newImage
    }
}
Bùi Đức Khánh
  • 3,975
  • 6
  • 27
  • 43