Save PNG image in PDF with lossless compression

I want to save a PNG image (created with screencapture) in a PDF with the image being saved with lossless (FlateDecode) compression. I can do this by opening the PNG image in Preview and saving it as a PDF. However, the following script saves it with lossy (DCTDecode) compression. I wondered if anyone might know the reason for that or how to change this?

BTW, I concluded that the image is saved in the PDF with DCTDecode compression based on the Xee3 image viewer and my inspection of the objects in the PDF. I don’t have Adobe Acrobat, which would be more definitive, but I think my conclusion is correct. Also, I tried different TIFF compression formats including none but that didn’t make a difference.

I know this is a bit convoluted, but I thought I would ask just in case. Thanks for reading my request.

use framework "AppKit"
use framework "Foundation"
use framework "Quartz"
use scripting additions

set imageFile to POSIX path of (path to desktop) & "Source.png"
set imageFile to current application's |NSURL|'s fileURLWithPath:imageFile
set pdfFile to POSIX path of (path to desktop) & "Test.pdf"
set imageRep to (current application's NSBitmapImageRep's imageRepWithContentsOfURL:imageFile)
set theData to (imageRep's representationUsingType:(current application's NSTIFFFileType) |properties|:{NSTIFFCompression:(current application's NSTIFFCompressionLZW)})
set theImage to (current application's NSImage's alloc()'s initWithData:theData)
set thePDFPage to (current application's PDFPage's alloc's initWithImage:theImage)
set pdfDoc to current application's PDFDocument's new()
(pdfDoc's insertPage:thePDFPage atIndex:0)
pdfDoc's writeToFile:pdfFile

Just a shot in the dark: what if you don’t use any TIFF compression?

zevrix. Thanks for reading my post and for the suggestion.

I did try no compression by using NSTIFFCompressionNone and by setting the properties to missing value. In both instances, the PDF was created but the PNG was saved in the PDF with DCTDecode compression. Another thing I tried was NSPNGFileType but that also didn’t work.

I can see two other potential options which may or may not help in any way:

  1. There’s another method to write PDFDocument

- (BOOL)writeToFile:(NSString *)path withOptions:(NSDictionary<PDFDocumentWriteOption, id> *)options;

Some of these options are poorly documented (if at all). There might be an option to specify image compression settings. However, even if such option does exist, you might no be able to find it anywhere anyway. Try to google it.

  1. Create a Quartz Filter in ColorSync Utility with this setting:

image

To see if this filter makes any difference to your particular PDF with DCTDecode compression, try to resave it from Preview while applying this filter.

If it does indeed affect the compression type, then you can use this Quartz Filter in the aforementioned withOptions: dictionary:

[NSDictionary dictionaryWithObject:qf forKey:@"QuartzFilter"]

where qf is a filter you’ll need to create using this method:

+ (QuartzFilter *)quartzFilterWithURL:(NSURL *)aURL;

Be prepared that all these efforts will be fruitless no matter what.

Out of curiosity, how are you determining that it is using the DCT compression?

I took a screen shot and created a PDF using your script. I then extracted its embedded image and looked at it using xee and it specifies that the compression scheme is ‘deflate’. Looking at the image with imagemagick’s identify shows ‘zip’ as the compression scheme, which presumably correlates to deflate.

One of the other PDF compression schemes has a lossless setting although I’m not sure how you would access it — JPXDecode.

Also, have you looked at the PDF/X format? It is designed for prepress and lossy compression is not an option with it. Again, not sure how you access it for general use without Acrobat (or other specialized software).

1 Like

PDF/X does accept JPEG (lossy) compression - in fact, it’s the default option in Adobe’s settings.

Not that it makes any difference in this particular case as, like you mentioned, he’d need Adobe tools to use options anyway.

That’s version 1 of the standard, released two decades ago. I believe it was removed in the next release. They may have added some form of compression in the most recent release as well but I’m not certain — there are some things I don’t need to know.

I think there are other tools that can generate PDF/X but like Adobe’s tools, I’m not sure that they’re intended for casual users. Ghostscript might have the wherewithal (as well as any products that are built upon it) but that’s another research project.

@zevrix. Thanks for the suggestions. I’ll give them a try.

@Mockman. I made the compression determination primarily by viewing the objects inside of the PDF. The object for the PNG image in the Preview-created PDF was:

5 0 obj
<< /Type /XObject /Subtype /Image /Width 1920 /Height 2070 /Interpolate true
/ColorSpace 6 0 R /Intent /Perceptual /BitsPerComponent 8 /Length 443292 /Filter
/FlateDecode >>

The object for the PNG image inside the script-created PDF was:

5 0 obj
<< /Type /XObject /Subtype /Image /Width 1920 /Height 2070 /Interpolate true
/ColorSpace 6 0 R /BitsPerComponent 8 /Length 682199 /Filter /DCTDecode >>

I also viewed the PDFs in Xee3 and object 5 in the Preview-created PDF is shown as a TIFF and object 5 in the script-created PDF is shown as a JPEG. They are not actually a JPEG or TIFF, and I assume this simply reflects the type of compression used.

Adobe Acrobat Pro apparently has (or used to have) an object viewer identified as “Browse Internal PDF Structure” accessible from the Advanced menu, and this would be determinative, but I don’t have that app. This is discussed here

The results you are getting when extracting the PNG image from the PDFs is interesting. I only have a basic understanding of the operation of PDFs and perhaps I just don’t understand what is happening here.

Thanks again.

Lossy compression is the default in all PDF/X standards. PDF/X-4 is the latest.

I worked in prepress for couple decades. While the compression is in theory “lossy”, under Maximum setting there’s no loss detectable by human eye.

@peavine
Here you could read about PNG on Adobe website.
https://www.adobe.com/creativecloud/file-types/image/raster/png-file.html