Docs: Compacting
Download PDF Changelog

Compacting PDFs

New in 1.15.0.

PdfCompactor makes an existing PDF smaller, any PDF, not only those PdfPecker made. By default nothing visible changes: the pages, bookmarks, links, forms, tags, attachments and PDF/A and PDF/UA conformance are kept, and every image keeps its exact pixels.

// Lossless: the same pages, in fewer bytes.
byte[] smaller = PdfCompactor.Compact(File.ReadAllBytes("merged.pdf"));

// Smaller still: images above 150 dpi downsampled, and photos recompressed as JPEG at quality 75.
byte[] smallest = PdfCompactor.Compact(pdf, new PdfCompactOptions { MaxImageDpi = 150, ImageQuality = 75 });

// Streams in and out; nothing is written when the input cannot be compacted.
PdfCompactor.Compact(inputStream, outputStream);

What it does

The document is written out again with only the objects its pages and catalog still use, so earlier revisions kept by incremental updates and orphaned objects go. Identical objects are stored once, such as the same font or image embedded many times, which merging documents often leaves behind. Streams with lossless filters are recompressed at the strongest Flate level, with PNG predictors for images, whenever that is smaller; JPEG, JPEG 2000, JBIG2 and CCITT images keep their data. Objects are written in minimal syntax and packed into compressed object streams.

The result depends only on the input and the options, so the same PDF always gives the same bytes. When rewriting does not make the file smaller, the input comes back unchanged.

Options

Option Default What it does
ImageQuality null Re-encodes 8-bit greyscale and RGB images as JPEG at this quality (1 to 100) where that makes them smaller. 75 to 85 suits most documents. This is lossy, also for images that were not JPEGs, such as screenshots and logos.
MaxImageDpi null Downsamples 8-bit greyscale and RGB images drawn at a higher resolution than this, judged by the largest size each image is drawn at on any page. A downsampled JPEG is re-encoded as JPEG (at ImageQuality, or 85); other images stay lossless unless ImageQuality is set. 150 suits the screen, 300 print.
RemoveMetadata false Removes the document information (title, author, dates) and XMP metadata. They are kept when the PDF claims PDF/A or PDF/UA, which require them.
RemoveApplicationData true Removes page thumbnails, which viewers draw themselves, and the private data editing applications keep in the file (/PieceInfo, such as Illustrator's editable copy), which no viewer shows.
UseObjectStreams true Packs objects into compressed object streams with a cross-reference stream (PDF 1.5, which every current reader supports). Turn it off for readers from before 2003. PDF/A-1 files never use them, as PDF/A-1 does not allow them.

An overload takes a CancellationToken, which stops the work between objects.

Signed and encrypted PDFs

Digitally signed PDFs are refused with ArgumentException, because rewriting them breaks the signatures. Compact before signing instead. Encrypted PDFs are refused too, since a rewrite would drop their protection: decrypt with PdfProtector.Decrypt, compact, and encrypt the result again with PdfProtector.Encrypt (see PDF/A, passwords and watermarks). A file that is not a readable PDF throws InvalidDataException.

Edit this page on GitHub