Reputation: 3060
I am developing application for Mac OS , i am not able to find any method for compressing
NSImage and Converting them to base64
encoded string for Swift 4 .
Hardly i found Swift3 code
func compressUnderMegaBytes(megabytes: CGFloat) -> NSImage? {
var compressionRatio = 1.0
var imageRep = NSBitmapImageRep(data: self.tiffRepresentation!)
var options = NSDictionary(object: NSNumber(floatLiteral: compressionRatio), forKey: NSBitmapImageRep.PropertyKey.compressionFactor as NSCopying)
var compressedData: Data? = imageRep?.representation(using: .jpeg, properties: options as! [NSBitmapImageRep.PropertyKey : Any])
while compressedData?.length > (megabytes * 1024 * 1024) {
compressionRatio = compressionRatio * 0.9
options = NSDictionary(object: NSNumber(floatLiteral:compressionRatio), forKey: NSBitmapImageRep.PropertyKey.compressionFactor as NSCopying)
compressedData = imageRep?.representation(using:.png, properties: options as! [NSBitmapImageRep.PropertyKey : Any])
if compressionRatio <= 0.4 {
break
}
}
return NSImage(data: compressedData!)
}
but after converting to Swift 4 getting following error
Upvotes: 1
Views: 1335
Reputation: 285290
The translated code is quite cumbersome. The NSDictionary
detour is not necessary in Swift 4.
length
has been renamed to count
extension NSImage {
func compressUnderMegaBytes(megabytes: CGFloat) -> NSImage? {
var compressionRatio = 1.0
guard let tiff = self.tiffRepresentation, let imageRep = NSBitmapImageRep(data: tiff) else { return nil }
var compressedData = imageRep.representation(using: .jpeg, properties: [.compressionFactor : compressionRatio])!
while CGFloat(compressedData.count) > megabytes * 1024 * 1024 {
compressionRatio = compressionRatio * 0.9
compressedData = imageRep.representation(using: .png, properties: [.compressionFactor : compressionRatio])!
if compressionRatio <= 0.4 {
break
}
}
return NSImage(data: compressedData)
}
}
Or without unsafe unwrapped optionals
extension NSImage {
func compressUnderMegaBytes(megabytes: CGFloat) -> NSImage? {
var compressionRatio = 1.0
guard let tiff = self.tiffRepresentation, let imageRep = NSBitmapImageRep(data: tiff) else { return nil }
var compressedData = imageRep.representation(using: .jpeg, properties: [.compressionFactor : compressionRatio])
if compressedData == nil { return self }
while CGFloat(compressedData!.count) > megabytes * 1024 * 1024 {
compressionRatio = compressionRatio * 0.9
let newCompressedData = imageRep.representation(using: .png, properties: [.compressionFactor : compressionRatio])
if compressionRatio <= 0.4 || newCompressedData == nil {
break
}
compressedData = newCompressedData
}
return NSImage(data: compressedData!)
}
}
Note: Is it intended to compress the first time as jpg
and then as png
?
Upvotes: 2