3

So, this is what I need :

  • Take an NSImage
  • Compress it as much as possible (loseless compress, no obvious drop in quality)
  • Save it back to disk

In the past, I tried using OptiPNG - as compiled binary (and getting results asynchronously) - which worked.

However, what if I don't want a terminal-like solution with external apps, but something more Cocoa-native?

Any ideas?

Charles
  • 50,943
  • 13
  • 104
  • 142
Dr.Kameleon
  • 22,532
  • 20
  • 115
  • 223
  • possible duplicate of [How to save a NSImage as a new file](http://stackoverflow.com/questions/3038820/how-to-save-a-nsimage-as-a-new-file) – Rob Napier Sep 08 '12 at 14:03

1 Answers1

-1
NSImage* image; // your NSImage

// With compression
NSData* data = [image
                TIFFRepresentationUsingCompression:NSTIFFCompressionLZW
                factor:0.5f]; // you can change factor between 0 and 1.0 for preferred compression rate

if (data != nil) {
    NSBitmapImageRep* bitmap = [[NSBitmapImageRep alloc] initWithData:data];
    if (bitmap != nil) {
        NSData* bitmapData = [bitmap
                              representationUsingType:NSBitmapImageFileTypePNG
                              properties:@{}];
        if (bitmapData != nil) {
            [bitmapData
             writeToFile:<file_path> //path where to save png
             atomically:true];
        }
    }
}

Update: As mentioned in comments, this does not compress png.
However I have used this code in ShareExtension and it compress received screenshots well (from 1.1-1.5MB if save in plain to 0.4-0.7MB using representationUsingType) and without quality loss, just like OP asked.

Alex
  • 79
  • 3
  • This doesn't actually compress the PNG. All it is doing is indicating that the TIFF should be compressed with LZW, which is lossless. So the reconstituted image will generate a PNG of the same size, regardless of what the compression factor is. – marcprux Mar 17 '20 at 21:34
  • Try varying the compression factor in this code. The resulting `bitmapData` will be the exact same size regardless of the `NSTIFFCompressionLZW` factor. – marcprux Mar 18 '20 at 19:01