CoreGraphics resizing function from iOS (UIImage) to MacOS (NSImage)
Hi Matthias,
Were you able to run your helper functions on MacOS? I replaced iOS (UIImage) to MacOS (NSImage), and got almost everything to work... Only the cgImage.bitsPerPixel part I didn't find a MacOS equivalent.
Have you tried running it on MacOS?
Cheers from Sweden! Alex
https://stackoverflow.com/questions/67202976/coregraphics-resizing-function-from-ios-uiimage-to-macos-nsimage
What I did: Code bellow
Problem: Getting error on this line of code: let bytesPerPixel = cgImage.bitsPerPixel / bitsPerComponent
Error: Value of type '(UnsafeMutablePointer?, NSGraphicsContext?, [NSImageRep.HintKey : Any]?) -> CGImage?' (aka '(Optional<UnsafeMutablePointer>, Optional, Optional<Dictionary<NSImageRep.HintKey, Any>>) -> Optional') has no member 'bitsPerPixel'
iOS: UIImage
extension UIImage {
// Resizeing using CoreGraphics
func resize(to size:CGSize) -> UIImage? {
let cgImage = self.cgImage!
let destWidth = Int(size.width)
let destHeight = Int(size.height)
let bitsPerComponent = 8
let bytesPerPixel = cgImage.bitsPerPixel / bitsPerComponent
let destBytesPerRow = destWidth * bytesPerPixel
let context = CGContext(data: nil,
width: destWidth,
height: destHeight,
bitsPerComponent: bitsPerComponent,
bytesPerRow: destBytesPerRow,
space: cgImage.colorSpace!,
bitmapInfo: cgImage.bitmapInfo.rawValue)!
context.interpolationQuality = .high
context.draw(cgImage, in: CGRect(origin: CGPoint.zero, size: size))
return context.makeImage().flatMap { UIImage(cgImage: $0) }
}
}
MacOS: NSImage
extension NSImage {
// Resizeing using CoreGraphics
func resize(to size:CGSize) -> NSImage? {
let cgImage = self.cgImage
let destWidth = Int(size.width)
let destHeight = Int(size.height)
let bitsPerComponent = 8
let bytesPerPixel = cgImage.bitsPerPixel / bitsPerComponent
let destBytesPerRow = destWidth * bytesPerPixel
let context = CGContext(data: nil,
width: destWidth,
height: destHeight,
bitsPerComponent: bitsPerComponent,
bytesPerRow: destBytesPerRow,
space: cgImage.colorSpace!,
bitmapInfo: cgImage.bitmapInfo.rawValue)!
context.interpolationQuality = .high
context.draw(cgImage, in: CGRect(origin: CGPoint.zero, size: size))
return context.makeImage().flatMap { NSImage(cgImage: $0) }
}
}
CGImage should work both on iOS and macOS. It looks like you forgot to unwrap self.cgImage, since the error message is about using an optional, not about CGImage itself.
Thanks Matthias!
I unwrapped self.cgImage, but got same error.
Looks like bitsPerPixel is only available for iOS... : /
Any idea what would be MacOS equivalent to bitsPerPixel?
/* Return the number of bits/pixel of `image'. */
**@available(iOS 2.0, *)**
public var bitsPerPixel: Int { get }
Value of type '(UnsafeMutablePointer<NSRect>?, NSGraphicsContext?, [NSImageRep.HintKey : Any]?) -> CGImage?' (aka '(Optional<UnsafeMutablePointer<CGRect>>, Optional<NSGraphicsContext>, Optional<Dictionary<NSImageRep.HintKey, Any>>) -> Optional<CGImage>') has no member 'bitsPerPixel'
Ah I see what's going on, NSImage.cgImage is not a property but a function. Namely the function:
func cgImage(forProposedRect proposedDestRect: UnsafeMutablePointer<NSRect>?, context referenceContext: NSGraphicsContext?, hints: [NSImageRep.HintKey : Any]?) -> CGImage?
You're trying to call bitsPerPixel on the function itself, not on the CGImage that comes out of the function. ;-)
thanks for spotting that Matthias! : )
Weird that UIImage.cgImage is a property, and NSImage.cgImage is a function.
Im a bit lost here... Do you have any idea what the final resize function would look like for MacOS?
Check out this StackOverflow answer: https://stackoverflow.com/questions/11949250/how-to-resize-nsimage
Thanks again!
Finally made it work with some help from Apple, this is the final function in case you also need. : )
// Resizeing using CoreGraphics
func resize(to size:CGSize) -> NSImage? {
let cgImage: CGImage = self.cgImage( forProposedRect: nil, context: nil, hints: nil)!
let destWidth = Int(size.width)
let destHeight = Int(size.height)
let bitsPerComponent = 8
let bytesPerPixel = cgImage.bitsPerPixel / bitsPerComponent
let destBytesPerRow = destWidth * bytesPerPixel
let context = CGContext(data: nil,
width: destWidth,
height: destHeight,
bitsPerComponent: bitsPerComponent,
bytesPerRow: destBytesPerRow,
space: cgImage.colorSpace!,
bitmapInfo: cgImage.bitmapInfo.rawValue)!
context.interpolationQuality = .high
context.draw(cgImage, in: CGRect(origin: CGPoint.zero, size: size))
return context.makeImage().flatMap { NSImage(cgImage: $0, size: NSSize(width: 1024, height: 1024)) }
}