Shrink a PDF in-memory with CompressOptions. Three presets cover the common cases: strict (default), lossy, and archival.
use pdfluent::prelude::*;
fn main() -> Result<()> {
let mut doc = PdfDocument::open("report.pdf")?;
let report = doc.compress(CompressOptions::strict())?;
println!("streams compressed: {}", report.streams_compressed);
println!("duplicates deduplicated: {}", report.streams_deduplicated);
println!("unused objects removed: {}", report.unused_removed);
if let Some(fs) = &report.font_subset {
println!("fonts subsetted: {} / {}", fs.fonts_subsetted, fs.fonts_processed);
println!("bytes saved (fonts): {}", fs.bytes_saved);
}
doc.save_with(
"report_compressed.pdf",
SaveOptions::new().with_overwrite(true),
)?;
Ok(())
}compress takes &mut self and rewrites the in-memory document. You save afterwards to persist.
use pdfluent::prelude::*;
let mut doc = PdfDocument::open("report.pdf")?;CompressOptions::strict() is the default and enables every pass: font subsetting, stream compression, duplicate-stream deduplication, unused-object removal. CompressOptions::lossy() matches strict() today; it reserves the slot for 1.1 lossy image downsampling. CompressOptions::archival() keeps unused objects (safer for incremental updates and signed appearance streams).
// full stack — recommended default
let opts = CompressOptions::strict();
// reserved for 1.1 lossy passes; today identical to strict
let opts = CompressOptions::lossy();
// keep unused objects — safest for signed / incremental-update docs
let opts = CompressOptions::archival();compress returns a CompressReport with counters for each pass. font_subset is an Option<FontSubsetReport> — None when font subsetting is disabled, Some with per-pass counters otherwise.
let report = doc.compress(CompressOptions::strict())?;
println!("streams compressed: {}", report.streams_compressed);
println!("streams deduplicated: {}", report.streams_deduplicated);
println!("unused removed: {}", report.unused_removed);
if let Some(fs) = &report.font_subset {
println!("fonts subsetted: {} of {}", fs.fonts_subsetted, fs.fonts_processed);
println!("font bytes saved: {}", fs.bytes_saved);
}save_with lets you opt into overwrite. Without with_overwrite(true), the SDK refuses to clobber an existing file (RFC 0001 §1.2). Point it at a new filename to skip the flag.
doc.save_with(
"report_compressed.pdf",
SaveOptions::new().with_overwrite(true),
)?;No JVM, no runtime, no DLL dependencies. Ships as a single native binary or WASM module.
Rust's ownership model prevents buffer overflows and use-after-free. No segfaults in PDF parsing.
Same code runs server-side, in Docker, on AWS Lambda, on Cloudflare Workers, or in the browser via WASM.