CoreGraphics resizing function from iOS (UIImage) to MacOS (NSImage)
alelordelo opened this issue · comments
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
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, 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?, NSGraphicsContext?, [NSImageRep.HintKey : Any]?) -> CGImage?' (aka '(Optional<UnsafeMutablePointer>, Optional, Optional<Dictionary<NSImageRep.HintKey, Any>>) -> Optional') 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)) }
}