PDF Oxide vs PyMuPDF
O PDF Oxide é a alternativa ao PyMuPDF com licença MIT: 5,8× mais rápido e sem o custo de conformidade que a AGPL impõe. Se você está avaliando o PyMuPDF para um produto comercial ou pensando em substituí-lo por causa do licenciamento, esta página cobre as diferenças que importam.
Por que as equipes estão migrando do PyMuPDF
Licença. O PyMuPDF empacota o MuPDF sob AGPL-3.0. Se você distribui software que inclui o PyMuPDF — SaaS, aplicação web ou imagem Docker, sem exceção — precisa abrir todo o código sob AGPL ou comprar uma licença comercial da Artifex. O PDF Oxide é MIT, sem amarras.
Velocidade. O PDF Oxide extrai texto em média de 0,8 ms; o PyMuPDF, em 4,6 ms. Sobre 3 830 PDFs, é uma diferença de 5,8×.
Confiabilidade. No mesmo corpus, o PDF Oxide passa 100 %. O PyMuPDF fica em 99,3 % e falha em 27 PDFs válidos.
Comparativo rápido
| PDF Oxide | PyMuPDF | |
|---|---|---|
| Licença | MIT | AGPL-3.0 |
| Tempo médio de extração | 0,8 ms | 4,6 ms |
| Taxa de sucesso (3 830 PDFs) | 100 % | 99,3 % |
| Extração de texto | Sim | Sim |
| Posições de caracteres | Sim | Sim |
| Extração de imagens | Sim | Sim |
| Campos de formulário | Ler + escrever | Ler + escrever |
| Criação de PDF | Sim (Markdown/HTML) | Sim |
| Saída Markdown | Sim | Não |
| Saída HTML | Sim | Não |
| Criptografia | Ler + escrever | Ler + escrever |
| Renderização | Sim | Sim |
| OCR | Embutido (PaddleOCR) | Tesseract |
| Tamanho de instalação | ~5 MB | ~20 MB |
| Versões de Python | 3.8–3.14 | 3.8–3.12 |
Código lado a lado
Extração de texto
PDF Oxide:
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
text = doc.extract_text(0)
print(text)
PyMuPDF:
import fitz
doc = fitz.open("report.pdf")
page = doc[0]
text = page.get_text()
print(text)
Conversão para Markdown
PDF Oxide (embutido):
from pdf_oxide import PdfDocument
doc = PdfDocument("paper.pdf")
md = doc.to_markdown(0, detect_headings=True)
print(md)
PyMuPDF:
# O PyMuPDF não tem conversão para Markdown.
# Usa-se pymupdf4llm (pacote separado, 69x mais lento que o PDF Oxide):
import pymupdf4llm
md = pymupdf4llm.to_markdown("paper.pdf")
Extração de imagens
PDF Oxide:
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
images = doc.extract_image_bytes(0)
for i, img in enumerate(images):
with open(f"image_{i}.{img['format']}", "wb") as f:
f.write(img["data"])
PyMuPDF:
import fitz
doc = fitz.open("report.pdf")
page = doc[0]
for i, img in enumerate(page.get_images()):
xref = img[0]
base_image = doc.extract_image(xref)
with open(f"image_{i}.{base_image['ext']}", "wb") as f:
f.write(base_image["image"])
Criar PDF a partir de Markdown
PDF Oxide:
from pdf_oxide import Pdf
pdf = Pdf.from_markdown("# Invoice\n\n| Item | Price |\n|------|-------|\n| Widget | $9.99 |")
pdf.save("invoice.pdf")
PyMuPDF:
import fitz
# O PyMuPDF não gera PDFs a partir de Markdown.
# Você precisa posicionar o texto manualmente nas páginas:
doc = fitz.open()
page = doc.new_page()
page.insert_text(fitz.Point(72, 72), "Invoice", fontsize=24)
doc.save("invoice.pdf")
Detalhes do benchmark
Medido sobre 3 830 PDFs vindos de três suítes de teste públicas e independentes (veraPDF, Mozilla pdf.js, DARPA SafeDocs).
| Métrica | PDF Oxide | PyMuPDF |
|---|---|---|
| Tempo médio de extração | 0,8 ms | 4,6 ms |
| Tempo p99 | 9 ms | 28 ms |
| Taxa de sucesso (PDFs válidos) | 100 % (3 823/3 823) | 99,3 % (3 796/3 823) |
| Paridade de qualidade do texto | 99,5 % | Referência |
Veja a metodologia completa do benchmark para detalhes do corpus e passos de reprodução.
AGPL: o que isso significa na prática
O PyMuPDF encapsula o MuPDF, que está sob AGPL-3.0. Isso afeta você se:
- Distribui software que usa PyMuPDF (binários, imagens Docker, apps Electron)
- Opera um SaaS em que o PyMuPDF processa PDFs de usuários nos seus servidores
- Embute o PyMuPDF em um produto — inclusive como microsserviço atrás de uma API
Em qualquer desses cenários, a AGPL exige que você libere todo o código da sua aplicação sob AGPL-3.0 — ou compre uma licença comercial da Artifex.
O PDF Oxide é MIT. Use em qualquer projeto — comercial, proprietário, SaaS ou open source — sem obrigações extras.
| Caso de uso | PDF Oxide (MIT) | PyMuPDF (AGPL) |
|---|---|---|
| Produto comercial | Sim | Requer licença |
| SaaS de código fechado | Sim | Requer licença |
| Ferramentas internas | Sim | Sim |
| Projeto open source | Sim | Sim (se for compatível com AGPL) |
| Distribuição via Docker | Sim | Requer licença |
Preço da licença comercial do PyMuPDF
A Artifex (empresa por trás do MuPDF e do PyMuPDF) não publica tabela de preços. Segundo relatos do mercado:
- Exige contato — é preciso solicitar um orçamento ao time comercial da Artifex
- Licença por aplicação — o preço varia conforme o tipo de implantação e a escala
- Mensalidade anual — licenças comerciais costumam ser renovadas todos os anos
- Sem plano gratuito — a AGPL não prevê exceção para “comunidade” ou “startup”
Para quem avalia o PyMuPDF com finalidade comercial, a licença é um custo operacional contínuo que se soma ao tempo de desenvolvimento.
O PDF Oxide é MIT — gratuito para qualquer uso, para sempre. Sem ligações de venda, sem auditoria de licença, sem risco de compliance. Use em SaaS, distribua em Docker, embuta em produtos comerciais — sem restrições.
Guia de migração
Mapeamento de APIs
| Tarefa | PyMuPDF | PDF Oxide |
|---|---|---|
| Abrir PDF | fitz.open("f.pdf") |
PdfDocument("f.pdf") |
| Número de páginas | doc.page_count |
doc.page_count() |
| Extrair texto | doc[0].get_text() |
doc.extract_text(0) |
| Dados por caractere | doc[0].get_text("dict") |
doc.extract_chars(0) |
| Extrair imagens | doc[0].get_images() + doc.extract_image(xref) |
doc.extract_images(0) |
| Buscar texto | doc[0].search_for("query") |
doc.search_page(0, "query") |
| PDF criptografado | doc.authenticate("pw") |
PdfDocument("f.pdf", password="pw") |
| Para Markdown | pymupdf4llm (separado) | doc.to_markdown(0) |
| Criar a partir de texto | insert_text() manual |
Pdf.from_markdown("# Título") |
Passo a passo
- Instale:
pip install pdf_oxide - Troque os imports:
import fitz→from pdf_oxide import PdfDocument - Troque a abertura:
fitz.open(path)→PdfDocument(path) - Troque a extração:
page.get_text()→doc.extract_text(page_index) - Troque as imagens: lookup de xref em vários passos →
doc.extract_images(page_index) - Ajuste a senha: use
PdfDocument(path, password="pw")ou chamedoc.authenticate("pw")depois de abrir - Teste: rode sua pipeline sobre os arquivos de teste que você já tem
Quando continuar no PyMuPDF
- Você já tem uma licença comercial do MuPDF e depende da renderização específica dele
- Precisa exportar para SVG (o PDF Oxide não gera SVG)
- O seu projeto já é AGPL
Páginas relacionadas
- Benchmarks de performance — resultados completos do corpus
- vs bibliotecas PDF de Python — todas as bibliotecas comparadas
- Começando com Python — instalação e primeira extração