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

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 osimport pymupdf # PyMuPDF# Diretório das imagensimgdir = "./resultados"# Listar os arquivos e ordenar corretamente pelo número da páginadef 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 corretamenteimglist = sorted(os.listdir(imgdir), key=extrair_numero)imgcount = len(imglist) # Contagem de imagensprint(f"Qtde de imagens: {imgcount}")# Criar documento PDFdoc = pymupdf.open()# Fator de escala para redimensionamento (1.0 = tamanho original, 0.5 = 50% do tamanho original)scale_factor = 5.5for i, f in enumerate(imglist):img_path = os.path.join(imgdir, f)# Verifica se o arquivo é uma imagem PNG antes de processarif not f.lower().endswith(".png"):print(f"Ignorando arquivo não-PNG: {f}")continue# Abrir a imagem como documento PDFimg = pymupdf.open(img_path)rect = img[0].rect # Dimensões da imagempdfbytes = img.convert_to_pdf() # Converter para fluxo PDFimg.close() # Fechar a imagem original# Abrir o PDF da imagem geradaimgPDF = pymupdf.open("pdf", pdfbytes)# Calcular as novas dimensões com o fator de escalanew_width = rect.width * scale_factornew_height = rect.height * scale_factor# Criar nova página com as dimensões da imagem redimensionadapage = doc.new_page(width=new_width, height=new_height)# Inserir a imagem na página redimensionadapage.show_pdf_page(page.rect, imgPDF, 0)print(f"Imagem {i + 1} adicionada: {f}")# Salvar o PDF finalpdf_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 osimport iofrom pdf2image import convert_from_pathfrom PIL import Image, ImageEnhanceimport fitz # PyMuPDFdef melhorar_contraste_pdf(entrada, saida_pasta, fator_contraste=1.5, dpi=150):os.makedirs(saida_pasta, exist_ok=True)# Converter PDF para imagensimagens = convert_from_path(entrada, dpi=dpi)doc = fitz.open()for i, img in enumerate(imagens):# Melhorar contrasteenhancer = ImageEnhance.Contrast(img)img_contraste = enhancer.enhance(fator_contraste)img_contraste = img_contraste.convert("RGB")# Converter para bytes em formato PNGimg_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 PDFwidth, height = img_contraste.sizeprint(f"larg:{width},alt:{height}")page = doc.new_page(width=width, height=height)# Inserir imagem na páginapage.insert_image(page.rect, stream=img_bytes.getvalue())print(f"Imagem {i + 1} processada e inserida no PDF.")# Salvar o PDF finalpdf_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 usomelhorar_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 # PyMuPDFdef rotacionar_pdf(entrada, saida, angulo=270):doc = fitz.open(entrada)for pagina in doc:pagina.set_rotation(angulo) # Rotação de X° conforme necessáriodoc.save(saida)doc.close()# Exemplo de usorotacionar_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 # PyMuPDFfrom PIL import Image, ImageEnhanceimport ioimport osdef processar_pdf(entrada_pdf, saida_pdf, contraste=1.5, nitidez=1.3, pasta_saida="resultados"):doc = fitz.open(entrada_pdf) # Abre o PDF originalnovo_pdf = fitz.open() # Novo documento para as páginas processadas# Garante que a pasta de saída existaos.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 imagempix = pagina.get_pixmap(dpi=150)img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)# Aplica melhorias na imagemimg = ImageEnhance.Contrast(img).enhance(contraste) # Aumenta o contrasteimg = ImageEnhance.Sharpness(img).enhance(nitidez) # Aumenta a nitidez# Divide a imagem ao meio (verticalmente)largura, altura = img.sizemetade_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 arquivodef 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 PDFwidth, height = imagem.sizeprint(f"larg:{width},alt:{height}")page = novo_pdf.new_page(width=width, height=height)# Inserir imagem na páginapage.insert_image(page.rect, stream=img_bytes.getvalue())# Adiciona as duas metades como novas páginasadicionar_pagina(metade_esquerda)adicionar_pagina(metade_direita)print(f"Página {num_pagina + 1} processada!")# Salva o novo PDF na pasta de saídapdf_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")