Skip to content

Стиснення PDF

DocumentEditor::save_with_options() за один прохід уміє перестискати потоки, прибирати осиротілі об’єкти збирачем сміття та лінеаризувати файл для швидкого перегляду в мережі. Найпростіший спосіб застосувати всі три — CLI pdf-oxide compress, яка ховає їх за єдиною командою.

Покриття біндингами. Повний SaveOptions із compress / garbage_collect / linearize доступний у Rust (editor.save_with_options(path, opts)) і Python (через doc.save(..., compress=True, ...) там, де його прив’язано). З Node, WASM, Go та C# запускайте CLI (pdf-oxide compress input.pdf -o out.pdf) як підпроцес або крок у збірці — CLI лишається стабільним інтерфейсом, який ці біндинги поділяють, доки SaveOptions не буде прокинуто через кожну FFI-поверхню.

CLI (усі платформи)

# Базово: створює input_compressed.pdf
pdf-oxide compress input.pdf

# Явне ім'я вихідного файлу
pdf-oxide compress input.pdf -o smaller.pdf

# Надрукувати порівняння розмірів
pdf-oxide compress report.pdf
# → Compressed report.pdf -> report_compressed.pdf (3412901 -> 1847200 bytes)

CLI за замовчуванням вмикає compress: true, garbage_collect: true, linearize: true — саме ця комбінація дає найменший файл, лишаючись валідним за ISO 32000.

Rust API

use pdf_oxide::editor::{DocumentEditor, EditableDocument, SaveOptions};

let mut editor = DocumentEditor::open("input.pdf")?;

editor.save_with_options("output.pdf", SaveOptions {
    compress: true,         // застосувати FlateDecode до всіх нестиснених потоків
    garbage_collect: true,  // прибрати осиротілі об'єкти
    linearize: true,        // лінеаризувати для швидкого перегляду в мережі
    ..Default::default()
})?;

Поля SaveOptions

Поле За замовчуванням Ефект
compress true у CLI / типово false Застосовує FlateDecode до потоків, що зберігалися нестисненими
garbage_collect true у CLI Прибирає непрямі об’єкти, на які більше не посилається трейлер
linearize true у CLI Записує лінеаризований («Fast Web View») макет, щоб перегляд показував 1-шу сторінку до повного завантаження файлу
encryption None Приєднує EncryptionConfig, щоб зберегти зашифровано — див. Шифрування і безпека

Що насправді робить кожна опція

  • compress — проходить по кожному content stream, Form XObject, ToUnicode CMap і потоку метаданих; якщо потік не має фільтра або має невідомий фільтр, перепаковує його у FlateDecode. Уже стиснені потоки (зображення JBIG2, таблиці CCITT, наявний Flate) не чіпає.
  • garbage_collect — запускає обхід досяжності від /Root і /Info, позначає кожен живий непрямий об’єкт і записує у вихідний xref лише їх. Корисно після масивних правок, коли remove_page, flatten_forms чи erase_region лишають осиротілі об’єкти.
  • linearize — переупорядковує об’єкти так, щоб content stream першої сторінки та її ресурсні залежності опинилися на початку файлу, додаючи словник лінеаризації та hint stream. PDF-рідери завантажують файл по порядку й відтворюють першу сторінку ще до завершення завантаження — це головна помітна користувачам перевага для PDF, які віддаються через CDN.

Коли стискати

  • Після масових правок — якщо ви запускали flatten_forms, flatten_all_annotations, apply_all_redactions або видалили багато сторінок, GC і перестиснення зазвичай зменшують розмір файлу на 30–60 %.
  • Перед розсилкою чи надсиланням поштою — кінцевим користувачам важливий розмір, а Linearize робить першу сторінку миттєво доступною навіть на повільних з’єднаннях.
  • Як останній крок ETL-конвеєра — після видобування та перегенерації стисніть один раз у кінці конвеєра; не розпаковуйте й не перестискайте на кожному перетворенні.

Коли стискати НЕ варто

  • Під час частих інкрементних правок — повні перезаписи руйнують xref stream і object stream, які тримають інкрементні дописування маленькими. Для інтерактивних циклів редагування використовуйте SaveOptions::incremental() і лишайте стиснення на фінальний прохід.
  • Для вже агресивно стиснених PDF — якщо у потоках уже встановлено FlateDecode із гарним predictor, можна виграти лише кілька відсотків. Запустіть pdf-oxide compress один раз і виміряйте, перш ніж вбудовувати його в конвеєр.

Очікувана економія розміру

Типова економія на реальних PDF (виміряно на тестовому наборі з 3830 файлів):

Джерело До Після Економія
Відсканований рахунок (нестиснені потоки) 2,4 МБ 0,8 МБ ~66 %
Наукова стаття у LaTeX 1,1 МБ 0,95 МБ ~14 %
Державна форма (після flatten) 890 КБ 240 КБ ~73 %
Уже оптимізований маркетинговий PDF 1,8 МБ 1,75 МБ ~3 %

Найбільший виграш дають масово редаговані файли та форми після вирівнювання. Уже оптимізовані файли мають скромну економію переважно за рахунок лінеаризації.

Спочатку розшифруйте / автентифікуйте

DocumentEditor наразі не має окремого виклику автентифікації паролем, тому зашифровані PDF потрібно розшифрувати першими. Використайте PdfDocument.open_with_password() для читання, збережіть незашифровану копію, а потім відкрийте цю копію в редакторі:

use pdf_oxide::api::Pdf;
use pdf_oxide::editor::{DocumentEditor, EditableDocument, SaveOptions};

let doc = Pdf::open_with_password("protected.pdf", "pw")?;
doc.save("temp-unencrypted.pdf")?;

let mut editor = DocumentEditor::open("temp-unencrypted.pdf")?;
editor.save_with_options("compressed.pdf", SaveOptions {
    compress: true,
    garbage_collect: true,
    linearize: true,
    ..Default::default()
})?;

Той самий підхід у Python через PdfDocument(path, password="pw") + save() + CLI.

Пов’язані сторінки