PDF Oxide vs PyMuPDF
PDF Oxide — альтернатива PyMuPDF с лицензией MIT: в 5,8 раза быстрее и без AGPL-груза в части комплаенса. Если вы выбираете PyMuPDF для коммерческого проекта или планируете уйти с него из-за лицензии, здесь собраны ключевые отличия.
Почему команды уходят с PyMuPDF
Лицензия. PyMuPDF оборачивает MuPDF под AGPL-3.0. Распространяете ПО с PyMuPDF — включая SaaS, веб-приложения и Docker-контейнеры — извольте открыть свой код по AGPL либо покупайте коммерческую лицензию у Artifex. PDF Oxide распространяется под MIT и не накладывает таких обязательств.
Скорость. PDF Oxide извлекает текст в среднем за 0,8 мс, PyMuPDF — за 4,6 мс. На выборке из 3 830 PDF это разница в 5,8 раза.
Надёжность. На том же корпусе PDF Oxide проходит 100 %, PyMuPDF — 99,3 % (27 падений на валидных PDF).
Краткое сравнение
| PDF Oxide | PyMuPDF | |
|---|---|---|
| Лицензия | MIT | AGPL-3.0 |
| Среднее время извлечения | 0,8 мс | 4,6 мс |
| Процент успехов (3 830 PDF) | 100 % | 99,3 % |
| Извлечение текста | Да | Да |
| Позиции символов | Да | Да |
| Извлечение изображений | Да | Да |
| Поля форм | Чтение + запись | Чтение + запись |
| Создание PDF | Да (Markdown/HTML) | Да |
| Вывод в Markdown | Да | Нет |
| Вывод в HTML | Да | Нет |
| Шифрование | Чтение + запись | Чтение + запись |
| Рендеринг | Да | Да |
| OCR | Встроенный (PaddleOCR) | Tesseract |
| Размер установки | ~5 МБ | ~20 МБ |
| Версии Python | 3.8–3.14 | 3.8–3.12 |
Код рядом
Извлечение текста
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)
Конвертация в Markdown
PDF Oxide (встроено):
from pdf_oxide import PdfDocument
doc = PdfDocument("paper.pdf")
md = doc.to_markdown(0, detect_headings=True)
print(md)
PyMuPDF:
# В PyMuPDF нет встроенной конвертации в Markdown.
# Используйте pymupdf4llm (отдельный пакет, в 69 раз медленнее PDF Oxide):
import pymupdf4llm
md = pymupdf4llm.to_markdown("paper.pdf")
Извлечение изображений
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"])
Создание PDF из 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
# PyMuPDF не умеет собирать PDF из Markdown.
# Текст придётся расставлять по странице вручную:
doc = fitz.open()
page = doc.new_page()
page.insert_text(fitz.Point(72, 72), "Invoice", fontsize=24)
doc.save("invoice.pdf")
Детали бенчмарка
Замеры на 3 830 PDF из трёх независимых публичных наборов (veraPDF, Mozilla pdf.js, DARPA SafeDocs).
| Метрика | PDF Oxide | PyMuPDF |
|---|---|---|
| Среднее время извлечения | 0,8 мс | 4,6 мс |
| Время p99 | 9 мс | 28 мс |
| Процент успехов (валидные PDF) | 100 % (3 823/3 823) | 99,3 % (3 796/3 823) |
| Паритет качества текста | 99,5 % | Базовая линия |
Подробнее о корпусе и шагах воспроизведения — в полной методологии бенчмарка.
Что значит AGPL на практике
PyMuPDF — обёртка над MuPDF, а MuPDF лицензирован по AGPL-3.0. Это касается вас, если:
- Вы распространяете ПО с PyMuPDF (бинарники, Docker-образы, Electron-приложения)
- Вы держите SaaS, где PyMuPDF обрабатывает PDF пользователей на ваших серверах
- Вы встраиваете PyMuPDF в продукт — в том числе как микросервис за API
Во всех этих случаях AGPL требует открыть весь исходный код приложения под AGPL-3.0 — либо купить коммерческую лицензию у Artifex.
PDF Oxide — MIT. Применяйте его в любом проекте — коммерческом, проприетарном, SaaS или open source — без обязательств.
| Сценарий | PDF Oxide (MIT) | PyMuPDF (AGPL) |
|---|---|---|
| Коммерческий продукт | Да | Нужна лицензия |
| SaaS с закрытым кодом | Да | Нужна лицензия |
| Внутренние инструменты | Да | Да |
| Проект с открытым кодом | Да | Да (если проект AGPL-совместим) |
| Раздача в Docker | Да | Нужна лицензия |
Стоимость коммерческой лицензии PyMuPDF
Artifex (компания, стоящая за MuPDF и PyMuPDF) не публикует прайс на коммерческие лицензии. По отраслевым данным:
- Нужен запрос — цену придётся уточнять у отдела продаж Artifex
- Лицензия на приложение — цена зависит от типа развёртывания и масштаба
- Ежегодная оплата — коммерческие лицензии обычно продлеваются раз в год
- Бесплатного тарифа нет — у AGPL не предусмотрено исключений для «комьюнити» или «стартапов»
Для команд, выбирающих PyMuPDF для коммерческого использования, лицензия — это постоянная операционная строка бюджета поверх времени разработчиков.
PDF Oxide — MIT, бесплатно для любого применения, навсегда. Никаких звонков от продажников, лицензионных аудитов и рисков комплаенса. SaaS, раздача в Docker, встраивание в коммерческие продукты — без ограничений.
Руководство по миграции
Соответствие API
| Задача | PyMuPDF | PDF Oxide |
|---|---|---|
| Открыть PDF | fitz.open("f.pdf") |
PdfDocument("f.pdf") |
| Количество страниц | doc.page_count |
doc.page_count() |
| Извлечь текст | doc[0].get_text() |
doc.extract_text(0) |
| Данные по символам | doc[0].get_text("dict") |
doc.extract_chars(0) |
| Извлечь изображения | doc[0].get_images() + doc.extract_image(xref) |
doc.extract_images(0) |
| Поиск текста | doc[0].search_for("query") |
doc.search_page(0, "query") |
| Зашифрованный PDF | doc.authenticate("pw") |
PdfDocument("f.pdf", password="pw") |
| В Markdown | pymupdf4llm (отдельно) | doc.to_markdown(0) |
| Создание из текста | insert_text() вручную |
Pdf.from_markdown("# Заголовок") |
Пошагово
- Установите:
pip install pdf_oxide - Замените импорты:
import fitz→from pdf_oxide import PdfDocument - Замените открытие:
fitz.open(path)→PdfDocument(path) - Замените извлечение:
page.get_text()→doc.extract_text(page_index) - Замените работу с изображениями: многоступенчатый поиск по xref →
doc.extract_images(page_index) - Обновите работу с паролем: используйте
PdfDocument(path, password="pw")либо после открытия вызовитеdoc.authenticate("pw") - Проверьте: прогоните свой пайплайн на существующих тестовых файлах
Когда остаться на PyMuPDF
- У вас уже есть коммерческая лицензия MuPDF и вы завязаны на его специфический рендеринг
- Нужен экспорт в SVG (PDF Oxide не выдаёт SVG)
- Ваш проект сам по себе уже под AGPL
Связанные страницы
- Бенчмарки производительности — полные результаты по корпусу
- vs Python-библиотеки для PDF — все библиотеки Python в сравнении
- Начало работы с Python — установка и первое извлечение