mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-29 12:38:58 -06:00
* M11: merge image fragments, and the Standard and Mobile optimizer presets Some PDF printers draw a page picture as thousands of images one pixel row high (one real page: 3,300 strips, 4.3 MB). The optimizer works image by image, a one-row image can't be resampled, and every JPEG strip carries its own headers, so Reduce File Size saved 2 bytes on it. - pdfcraft-optimize `fragments` (Settings::merge_fragments, on by default): runs of `q … cm /Im Do Q` drawing upright 8-bit grey or RGB images in one colour space, sharing their left and right edges and stacked edge to edge (at least four, nothing else drawn between them; or, failing that, the rows drawn one under the other up to a gap) become one lossless image at their finest resolution. The image settings then resample it, and Clean Up drops the strips. A page whose content can't be read back exactly is left alone. - Presets as in Acrobat's Settings menu: Standard (Reduce File Size's choices) and Mobile (images above 144 ppi to 96 ppi, JPEG high). The PDF Optimizer dialog has a Settings menu (Custom once an option changes) and a Merge image fragments box; doc_optimize takes preset and merge_fragments and reports merged_images and fragments_merged. - A progress stage for the merge; four new strings in all 21 catalogs. On the real page: Standard/Reduce 4.3 MB → 231 KB, Mobile → 161 KB, with a rendering closer to the original than Acrobat's Mobile result (147 KB). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Refresh catalog hashes after merging main --------- Co-authored-by: magdale76 <16279778+magdale76@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com>
38 lines
2.5 KiB
Markdown
38 lines
2.5 KiB
Markdown
# pdfcraft-optimize
|
|
|
|
Layer L4: the PDF Optimizer (execution plan M11.1; Acrobat's Reduce File Size and Optimize PDF ▸
|
|
Advanced optimization).
|
|
|
|
```rust
|
|
let report = optimize(&mut doc, &Settings::default())?; // Reduce File Size's choices
|
|
let report = optimize(&mut doc, &Preset::Mobile.settings())?; // smaller, for screens
|
|
// Or with progress: called before each image and the clean-up; `false` cancels.
|
|
let report = optimize_with_progress(&mut doc, &settings, &mut |stage| keep_going)?;
|
|
```
|
|
|
|
- **Presets:** Standard (Reduce File Size's choices: images above 225 ppi to 150 ppi, JPEG
|
|
medium) and Mobile (above 144 ppi to 96 ppi, JPEG high), as in Acrobat's Settings menu.
|
|
- **Merge image fragments** (`fragments`, on by default): some PDF printers draw a page picture
|
|
as thousands of images one pixel row high. Runs of upright 8-bit grey or RGB images in one
|
|
colour space, sharing their left and right edges and stacked edge to edge (at least four,
|
|
drawn with nothing else between them), become one lossless image at their finest resolution,
|
|
which the image settings then resample; the strips are dropped by Clean Up. A real page
|
|
printed this way went from 4.3 MB to 231 KB (Standard) and 161 KB (Mobile). Not merged yet:
|
|
side-by-side tiles, rotated strips, masks.
|
|
- **Images:** the effective resolution of each image is measured where pages draw it (the CTM
|
|
through form XObjects; the smallest over all uses). Colour and grayscale images above a
|
|
threshold are resampled with a bicubic (Catmull-Rom) filter to a target resolution and
|
|
stored as JPEG (Acrobat's quality steps) or ZIP; soft masks are resampled with their image.
|
|
An image is replaced only if the result is smaller. Left alone: CMYK and other colour spaces,
|
|
image masks, decode arrays, more than 8 bits, JPEG 2000, JBIG2 and CCITT.
|
|
- **Discard objects:** thumbnails, alternate images, document tags, print settings.
|
|
- **Clean up:** Flate for streams with no filter; for streams with an outer ASCII85 or ASCIIHex
|
|
layer, that layer is removed when the result is smaller (the inner filters keep their encoded
|
|
bytes). Streams with `/DecodeParms`, images and object streams are left alone.
|
|
|
|
The engine runs Remove Hidden Information (`pdfcraft-redact`) for the user-data categories,
|
|
then this, then merges identical objects and writes a full, compressed save
|
|
(`pdfcraft_engine::optimizer::OptimizeJob`, which the UI runs on a worker thread with a
|
|
progress bar). JPEG decoding and
|
|
encoding and resampling come from the `image` crate.
|