Python PDF Compress

Abaixo você encontra os procedimentos para configuração e o código-fonte em Python desenvolvido para comprimir e reduzir o tamanho de arquivos PDF através da rasterização de páginas e otimização de imagens.


Procedimento Operacional Padrão (POP)

1. Criar o ambiente virtual (venv) no Windows

Ainda não criou o seu ambiente localhost? Veja no link abaixo como fazer.


2. Instalar as bibliotecas Python

Com o ambiente virtual ativado, instale as bibliotecas externas PyMuPDF (fitz) e Pillow (PIL), necessárias para manipular o PDF e otimizar a qualidade das imagens:

pip install PyMuPDF Pillow

3. Como configurar o script


Código-Fonte

# REQUEST LIB PYTHON
import fitz  # PyMuPDF
from PIL import Image
import io


# compress keep img
def pdf_compress(
    input_path,
    output_path,
    dpi=120,  # 96–150 costuma ficar bom; mais baixo = mais leve
    quality=60,  # 40–70; menor = mais compressão
):
    # Abre o PDF original
    src_doc = fitz.open(input_path)

    # Novo PDF de saída
    out_doc = fitz.open()

    zoom = dpi / 72.0  # 72 dpi é a base do PDF
    mat = fitz.Matrix(zoom, zoom)

    for page_index in range(len(src_doc)):
        page = src_doc[page_index]

        # Renderiza página em imagem
        pix = page.get_pixmap(matrix=mat, alpha=False)
        size = (int(pix.width), int(pix.height))
        img = Image.frombytes("RGB", size, pix.samples)

        # Comprime imagem em JPEG
        img_bytes_io = io.BytesIO()
        img.save(img_bytes_io, format="JPEG", quality=quality, optimize=True)
        img_bytes = img_bytes_io.getvalue()

        # Cria uma página no novo PDF com o tamanho da imagem
        rect = fitz.Rect(0, 0, pix.width, pix.height)
        pdf_bytes = img_bytes

        # Transformamos a imagem JPEG em um PDF de uma página e anexamos
        img_pdf = fitz.open("pdf", fitz.open("jpeg", img_bytes).convert_to_pdf())
        out_page = out_doc.new_page(
            width=img_pdf[0].rect.width, height=img_pdf[0].rect.height
        )
        out_page.show_pdf_page(out_page.rect, img_pdf, 0)

    # Salva PDF final comprimido
    out_doc.save(output_path, deflate=True)
    out_doc.close()
    src_doc.close()


if __name__ == "__main__":
    pdf_compress(
        r"C:\test\pdf-big-size.pdf",  # 10MB
        r"C:\test\pdf-small-size.pdf",  # 100KB
        dpi=120,  # tente 120; se ainda ficar grande, abaixe para 96
        quality=60,  # se der, tente 50 para mais compressão
    )