Skip to content

Compressão de PDF

DocumentEditor::save_with_options() consegue recomprimir streams, fazer coleta de lixo em objetos órfãos e linearizar o arquivo para visualização web rápida — tudo em uma única passagem. O jeito mais fácil de aplicar os três é a CLI pdf-oxide compress, que embrulha tudo em um único comando.

Cobertura nos bindings. SaveOptions completo, com compress / garbage_collect / linearize, está exposto em Rust (editor.save_with_options(path, opts)) e Python (via doc.save(..., compress=True, ...) quando bindado). Em Node, WASM, Go e C#, execute a CLI (pdf-oxide compress input.pdf -o out.pdf) como subprocesso ou passo de build — a CLI é a interface estável que esses bindings compartilham até que SaveOptions seja cabeado em cada superfície FFI.

CLI (todas as plataformas)

# Básico: produz input_compressed.pdf
pdf-oxide compress input.pdf

# Saída explícita
pdf-oxide compress input.pdf -o smaller.pdf

# Imprime comparação de tamanho
pdf-oxide compress report.pdf
# → Compressed report.pdf -> report_compressed.pdf (3412901 -> 1847200 bytes)

A CLI habilita compress: true, garbage_collect: true, linearize: true por padrão — essa é a combinação que produz o menor arquivo mantendo-se válido conforme ISO 32000.

API Rust

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

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

editor.save_with_options("output.pdf", SaveOptions {
    compress: true,         // aplica FlateDecode em todos os streams não comprimidos
    garbage_collect: true,  // descarta objetos órfãos
    linearize: true,        // lineariza para visualização web rápida
    ..Default::default()
})?;

Campos de SaveOptions

Campo Padrão Efeito
compress true na CLI / false padrão Aplica FlateDecode a streams armazenados sem compressão
garbage_collect true na CLI Descarta objetos indiretos que não são mais referenciados pelo trailer
linearize true na CLI Emite o layout Linearizado (“Fast Web View”) para que os leitores renderizem a página 1 antes do arquivo inteiro baixar
encryption None Anexa um EncryptionConfig para salvar criptografado — ver Criptografia e segurança

O que cada opção realmente faz

  • compress — percorre todo content stream, Form XObject, ToUnicode CMap e stream de metadados; se o stream não tem filtro ou tem um filtro desconhecido, reembrulha com FlateDecode. Streams já comprimidos (imagens JBIG2, tabelas CCITT, Flate existente) ficam intocados.
  • garbage_collect — faz uma varredura de alcançabilidade a partir de /Root e /Info, marca cada objeto indireto vivo e grava só esses na xref de saída. Útil depois de edições pesadas em que remove_page, flatten_forms ou erase_region deixam órfãos.
  • linearize — reordena os objetos para que o content stream da primeira página e suas dependências de recurso apareçam no começo do arquivo, junto com um dicionário de linearização e um hint stream. Leitores de PDF baixam o arquivo em ordem e renderizam a página 1 antes de o arquivo inteiro chegar — esse é o principal benefício visível ao usuário em PDFs servidos por CDN.

Quando comprimir

  • Depois de edições em lote — se você rodou flatten_forms, flatten_all_annotations, apply_all_redactions ou apagou várias páginas, GC + recompressão costuma cortar 30 a 60% do tamanho do arquivo.
  • Antes de distribuir ou enviar por e-mail — o usuário final se importa com o tamanho, e o Linearize faz a primeira página parecer instantânea em conexões lentas.
  • Como último passo em pipelines ETL — depois da extração e regeneração, comprima uma única vez no final do pipeline; não descomprima e recomprima a cada transformação.

Quando NÃO comprimir

  • Durante edições incrementais frequentes — reescritas completas perdem xref streams e object streams que mantêm os appends incrementais pequenos. Em loops interativos de edição, use SaveOptions::incremental() e deixe a compressão para uma passagem final.
  • Em PDFs já comprimidos agressivamente — se os streams já têm filtros FlateDecode com um bom predictor, você pode economizar só alguns por cento. Rode pdf-oxide compress uma vez e meça antes de colocar no pipeline.

Expectativas de redução de tamanho

Economias típicas em PDFs do mundo real (medidas em um corpus de teste de 3.830 arquivos):

Origem Antes Depois Economia
Nota fiscal digitalizada (streams sem compressão) 2,4 MB 0,8 MB ~66 %
Artigo de pesquisa em LaTeX 1,1 MB 0,95 MB ~14 %
Formulário governamental (após flatten) 890 KB 240 KB ~73 %
PDF de marketing já otimizado 1,8 MB 1,75 MB ~3 %

Arquivos editados em massa e formulários após o flatten são os maiores ganhos. Arquivos já otimizados têm economia modesta vinda só da linearização.

Descriptografe / autentique primeiro

DocumentEditor ainda não traz uma chamada de autenticação por senha, então PDFs criptografados precisam ser descriptografados primeiro. Use PdfDocument.open_with_password() para ler, salve uma cópia não criptografada e depois abra essa cópia no editor:

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()
})?;

Mesmo padrão em Python via PdfDocument(path, password="pw") + save() + CLI.

Páginas relacionadas