Сжатие PDF
DocumentEditor::save_with_options() умеет за один проход пересжимать потоки, собирать мусор из бесхозных объектов и линеаризовать файл под быструю web-отдачу. Проще всего включить всё это разом с помощью 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, // линеаризовать под быструю web-отдачу
..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с хорошим предиктором, вы можете выиграть лишь пару процентов. Запустите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.
Связанные страницы
- Обзор редактирования —
SaveOptionsи вся поверхность редактора - Шифрование и безопасность — комбинируйте
compressсsave_with_encryption - Быстрый старт с CLI — все 22 команды CLI