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 із закритим кодом | Так | Потрібна ліцензія |
| Внутрішні інструменти | Так | Так |
| Open-source проєкт | Так | Так (якщо сумісний з AGPL) |
| Розповсюдження в Docker | Так | Потрібна ліцензія |
Ціна комерційної ліцензії PyMuPDF
Artifex (компанія за MuPDF та PyMuPDF) не публікує прайс на комерційні ліцензії. За галузевими даними:
- Потрібен запит — ціну дізнаєтеся лише у відділу продажів Artifex
- Ліцензія на застосунок — вартість залежить від типу розгортання й масштабу
- Щорічна оплата — комерційні ліцензії зазвичай продовжують щороку
- Безкоштовного тарифу немає — в AGPL немає винятків для «community» чи «startup»
Для команд, що розглядають 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 — встановлення й перше видобування