Editando PDFs com Python

13/02/2025

Códigos Python para a realização de edições em PDFs, como, por exemplo, conversão de páginas duplas em páginas simples, melhoria de contraste. Id: 50

Capa do artigo Editando PDFs com Python

Edição de PDFs

Neste artigo, vamos apresentar códigos Python destinados a editar PDFs, com a utilização das bibliotecas pyMuPDF, pdf2image, PIL.

Código 1: Agrupa Arquivos PNG em um único PDF

Este código demonstra como podemos agrupar arquivos PNG em um único PDF.

import os
import pymupdf # PyMuPDF
# Diretório das imagens
imgdir = "./resultados"
# Listar os arquivos e ordenar corretamente pelo número da página
def extrair_numero(nome_arquivo):
"""Extrai o número do nome do arquivo. Se não houver números, retorna um valor alto."""
numeros = "".join(filter(str.isdigit, nome_arquivo))
return int(numeros) if numeros else 999999 # Se não houver número, coloca no final
# Ordenar os arquivos corretamente
imglist = sorted(os.listdir(imgdir), key=extrair_numero)
imgcount = len(imglist) # Contagem de imagens
print(f"Qtde de imagens: {imgcount}")
# Criar documento PDF
doc = pymupdf.open()
# Fator de escala para redimensionamento (1.0 = tamanho original, 0.5 = 50% do tamanho original)
scale_factor = 5.5
for i, f in enumerate(imglist):
img_path = os.path.join(imgdir, f)
# Verifica se o arquivo é uma imagem PNG antes de processar
if not f.lower().endswith(".png"):
print(f"Ignorando arquivo não-PNG: {f}")
continue
# Abrir a imagem como documento PDF
img = pymupdf.open(img_path)
rect = img[0].rect # Dimensões da imagem
pdfbytes = img.convert_to_pdf() # Converter para fluxo PDF
img.close() # Fechar a imagem original
# Abrir o PDF da imagem gerada
imgPDF = pymupdf.open("pdf", pdfbytes)
# Calcular as novas dimensões com o fator de escala
new_width = rect.width * scale_factor
new_height = rect.height * scale_factor
# Criar nova página com as dimensões da imagem redimensionada
page = doc.new_page(width=new_width, height=new_height)
# Inserir a imagem na página redimensionada
page.show_pdf_page(page.rect, imgPDF, 0)
print(f"Imagem {i + 1} adicionada: {f}")
# Salvar o PDF final
pdf_saida = os.path.join(imgdir, "all-my-pics.pdf")
doc.save(pdf_saida)
doc.close()
print(f"PDF gerado: {pdf_saida}")

Código 2: Melhora o contraste

Este código melhora o contraste de páginas de um PDF.

import os
import io
from pdf2image import convert_from_path
from PIL import Image, ImageEnhance
import fitz # PyMuPDF
def melhorar_contraste_pdf(entrada, saida_pasta, fator_contraste=1.5, dpi=150):
os.makedirs(saida_pasta, exist_ok=True)
# Converter PDF para imagens
imagens = convert_from_path(entrada, dpi=dpi)
doc = fitz.open()
for i, img in enumerate(imagens):
# Melhorar contraste
enhancer = ImageEnhance.Contrast(img)
img_contraste = enhancer.enhance(fator_contraste)
img_contraste = img_contraste.convert("RGB")
# Converter para bytes em formato PNG
img_bytes = io.BytesIO()
#img_contraste.save(img_bytes, format="JPEG")
img_contraste.save(img_bytes, format="PNG", optimize=True, compress_level=9)
img_bytes.seek(0)
# Criar uma nova página do PDF
width, height = img_contraste.size
print(f"larg:{width},alt:{height}")
page = doc.new_page(width=width, height=height)
# Inserir imagem na página
page.insert_image(page.rect, stream=img_bytes.getvalue())
print(f"Imagem {i + 1} processada e inserida no PDF.")
# Salvar o PDF final
pdf_saida_path = os.path.join(saida_pasta, "saida_contraste.pdf")
doc.save(pdf_saida_path)
doc.close()
print(f"Processo concluído! Arquivo salvo em: {pdf_saida_path}")
# Exemplo de uso
melhorar_contraste_pdf("entrada.pdf", "resultados", fator_contraste=1.6, dpi=150)

Código 3: Rotaciona PDFs (PDF paisagem para PDF retrato e vice-versa, por exemplos)

Converte PDF de orientação paisagem para retrato.

import fitz # PyMuPDF
def rotacionar_pdf(entrada, saida, angulo=270):
doc = fitz.open(entrada)
for pagina in doc:
pagina.set_rotation(angulo) # Rotação de X° conforme necessário
doc.save(saida)
doc.close()
# Exemplo de uso
rotacionar_pdf("entrada.pdf", "saida.pdf", 90)

Código 4: converte PDFs de 2 páginas com orientação paisagem para páginas únicas em orientação retrato

import fitz # PyMuPDF
from PIL import Image, ImageEnhance
import io
import os
def processar_pdf(entrada_pdf, saida_pdf, contraste=1.5, nitidez=1.3, pasta_saida="resultados"):
doc = fitz.open(entrada_pdf) # Abre o PDF original
novo_pdf = fitz.open() # Novo documento para as páginas processadas
# Garante que a pasta de saída exista
os.makedirs(pasta_saida, exist_ok=True)
for num_pagina in range(len(doc)):
pagina = doc[num_pagina]
# Rotaciona a página em 90 graus no sentido horário (SE NECESSÁRIO)
# pagina.set_rotation(90)
# Converte a página para imagem
pix = pagina.get_pixmap(dpi=150)
img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
# Aplica melhorias na imagem
img = ImageEnhance.Contrast(img).enhance(contraste) # Aumenta o contraste
img = ImageEnhance.Sharpness(img).enhance(nitidez) # Aumenta a nitidez
# Divide a imagem ao meio (verticalmente)
largura, altura = img.size
metade_esquerda = img.crop((0, 0, largura // 2, altura))
metade_direita = img.crop((largura // 2, 0, largura, altura))
# Função para adicionar imagem ao novo PDF sem inflar o tamanho do arquivo
def adicionar_pagina(imagem):
img_bytes = io.BytesIO()
imagem.save(img_bytes, format="JPEG", quality=100) # Usa JPEG
#imagem.save(img_bytes, format="PNG", optimize=True, compress_level=9) # Não deu certo com PNG...
img_bytes.seek(0) # Garante que o ponteiro esteja no início
# Criar uma nova página do PDF
width, height = imagem.size
print(f"larg:{width},alt:{height}")
page = novo_pdf.new_page(width=width, height=height)
# Inserir imagem na página
page.insert_image(page.rect, stream=img_bytes.getvalue())
# Adiciona as duas metades como novas páginas
adicionar_pagina(metade_esquerda)
adicionar_pagina(metade_direita)
print(f"Página {num_pagina + 1} processada!")
# Salva o novo PDF na pasta de saída
pdf_saida_path = os.path.join(pasta_saida, saida_pdf)
novo_pdf.save(pdf_saida_path)
novo_pdf.close()
doc.close()
print(f"✅ Processo concluído! Arquivo salvo como {pdf_saida_path}")
# Exemplo de uso:
processar_pdf("Deitado.pdf", "pdf-retrato.pdf", contraste=1.6, nitidez=1.4, pasta_saida="resultados")

Veja os exemplos deste artigo no Youtube:

https://www.youtube.com/watch?v=eRYVt48EhJA

Para comentários:

Se quiser comentar, sugerir (acréscimos, retificações etc), criticar, elogiar, informar, sobre algum trecho deste artigo, peço a gentileza de utilizar a área de comentários do abaixo informada, no Youtube.

Já existe uma mensagem por lá dedicada a comentários sobre temas publicados neste portal.

Essa também é uma forma de contribuir com o trabalho e estimular sua continuidade e aprimoramento.

Peço a gentileza de comentar, curtir e compartilhar o conteúdo, além de se inscrever no canal do Youtube e ativar o sino de notificações para receber notícias de novos conteúdos.

Agradeço desde já!

Destinado para esses comentários em geral:

https://www.youtube.com/@roberto_csantos/community