PyMuPDF と pypdf — どちらの Python PDF ライブラリを選ぶべきか
PyMuPDF と pypdf は、最も人気のある Python PDF ライブラリのうちの 2 つですが、どちらにも大きなトレードオフがあります。PyMuPDF は高速ですが AGPL-3.0 ライセンスに縛られています。pypdf は寛容なライセンスですが、15 倍遅いです。このページでは両者を直接比較し、なぜ PDF Oxide がどちらよりも優れた選択肢なのかを示します。
結論を先に言うと: PDF Oxide は PyMuPDF より 5.8 倍、pypdf より 15 倍高速で、MIT ライセンスであり、両者よりも多くの機能を備えています。組み込みの Markdown / HTML 出力、XFA フォーム対応、システム依存のない OCR などです。
クイック比較
| PyMuPDF | pypdf | PDF Oxide | |
|---|---|---|---|
| ライセンス | AGPL-3.0 | BSD-3 | MIT |
| 言語 | C (MuPDF) | 純粋な Python | Rust + PyO3 |
| 平均抽出時間 | 4.6ms | 12.1ms | 0.8ms |
| p99 抽出時間 | 28ms | 97ms | 9ms |
| 合格率(3,830 件の PDF) | 99.3% | 98.4% | 100% |
| テキスト抽出 | あり | あり | あり |
| 文字位置 | あり | 部分的 | あり |
| 画像抽出 | あり | あり | あり |
| フォームフィールド | 読み取り + 書き込み | 読み取り + 書き込み | 読み取り + 書き込み |
| PDF 作成 | あり | 限定的(結合のみ) | あり(Markdown / HTML) |
| Markdown 出力 | なし | なし | あり |
| HTML 出力 | なし | なし | あり |
| レンダリング | あり | なし | あり |
| OCR | Tesseract | なし | 組み込み(PaddleOCR) |
| インストールサイズ | 約 20 MB | 約 1 MB | 約 5 MB |
| 暗号化 | 読み取り + 書き込み | 読み取り + 書き込み | 読み取り + 書き込み |
| 検索 | あり | なし | 正規表現 + 空間検索 |
| Python バージョン | 3.8–3.12 | 3.6+ | 3.8–3.14 |
PyMuPDF は pypdf よりも高速で機能が豊富ですが、その AGPL ライセンスは多くの商用プロジェクトにとって致命的な障害となります。pypdf はより軽量で BSD ライセンスですが、大幅に遅く、抽出機能も限られています。PDF Oxide はネイティブエンジンの速度面での利点と、寛容なライセンスによる自由度を兼ね備えています。
ライセンス:AGPL と BSD と MIT
PyMuPDF と pypdf のライセンスの違いは、両者を選ぶ際の決め手となることがよくあります。
PyMuPDF — AGPL-3.0
PyMuPDF は MuPDF をラップしており、MuPDF は AGPL-3.0 でライセンスされています。これは強いコピーレフトライセンスです。PyMuPDF を使用するソフトウェアを配布する場合(SaaS アプリケーション、Docker コンテナ、Web サービス、デスクトップアプリ、CLI ツールを含む)、アプリケーション全体を AGPL-3.0 でリリースしなければなりません。つまり、全ソースコードを同じライセンスで公開する必要があるということです。
その代替手段は、MuPDF の開発元である Artifex から商用ライセンスを購入することです。Artifex は価格を公開していないため、見積もりを得るには営業チームに問い合わせる必要があります。商用ライセンスは通常、年間契約でアプリケーションごとに価格が設定されます。
AGPL が影響するケース:
- PyMuPDF を含む製品を出荷する場合(デスクトップアプリ、モバイルアプリ、Electron)
- PyMuPDF で PDF を処理する SaaS または Web サービスを運用する場合
- PyMuPDF を含む Docker イメージを配布する場合
- 内部的に PyMuPDF を使用する API を提供する場合
AGPL が影響しないケース:
- プロジェクトがすでに AGPL 互換ライセンスでオープンソース化されている場合
- PyMuPDF を、決して配布しない内部ツールのためだけに使用する場合
pypdf — BSD-3
pypdf は寛容な BSD 3-Clause ライセンスを採用しています。pypdf は商用製品、クローズドソースソフトウェア、SaaS アプリケーションで、コードをオープンソース化する義務なしに使用できます。唯一の要件は、再配布時に著作権表示を保持することです。
PDF Oxide — MIT
PDF Oxide は MIT ライセンスです。最も寛容な一般的オープンソースライセンスです。ライセンステキストを含めること以外の制限なく、あらゆる文脈(商用、プロプライエタリ、SaaS、オープンソース)で使用できます。
ライセンスのまとめ
| ユースケース | PyMuPDF (AGPL) | pypdf (BSD) | PDF Oxide (MIT) |
|---|---|---|---|
| 商用製品 | ライセンスが必要 | 可 | 可 |
| クローズドソース SaaS | ライセンスが必要 | 可 | 可 |
| Docker 配布 | ライセンスが必要 | 可 | 可 |
| 内部ツール | 可 | 可 | 可 |
| オープンソース(AGPL 互換) | 可 | 可 | 可 |
| オープンソース(MIT/BSD/Apache) | 不可 | 可 | 可 |
ライセンス遵守が重要な商用プロジェクトでは、pypdf と PDF Oxide はどちらも安全な選択肢です。PyMuPDF は、アプリケーションのオープンソース化か商用ライセンスの購入のいずれかを必要とします。
速度ベンチマーク
すべてのベンチマークは、同一の 3,830 件の PDF コーパスで実行されました。これは 3 つの独立した公開テストスイート(veraPDF、Mozilla pdf.js、DARPA SafeDocs)で構成され、あらゆる PDF 仕様バージョン(1.0–2.0)、暗号化ファイル、CJK エンコーディング、複雑なレイアウト、不正な文書を網羅しています。
テキスト抽出速度
| ライブラリ | 平均 | p99 | PDF Oxide との比較 |
|---|---|---|---|
| PDF Oxide | 0.8ms | 9ms | 1x |
| PyMuPDF | 4.6ms | 28ms | 5.8 倍遅い |
| pypdf | 12.1ms | 97ms | 15.1 倍遅い |
PyMuPDF は解析を MuPDF の C エンジンに委ねているため、pypdf より 2.6 倍高速です。pypdf はすべてを純粋な Python で行うため(解析、フォントデコード、テキスト組み立て)、すべての処理でインタープリタのオーバーヘッドが発生します。
PDF Oxide が両者よりも高速なのは、その Rust コアがすべての PDF 解析、フォントデコード、テキストレイアウトを PyO3 経由でネイティブに処理し、最終結果のみが Python 境界を越えるためです。サブプロセスのオーバーヘッドも、ctypes を介した C ライブラリのブリッジングも、インタープリタのボトルネックもありません。
信頼性
| ライブラリ | 合格した有効な PDF | 合格率 |
|---|---|---|
| PDF Oxide | 3,823 / 3,823 | 100% |
| PyMuPDF | 3,796 / 3,823 | 99.3% |
| pypdf | 3,762 / 3,823 | 98.4% |
PyMuPDF はコーパス内の 27 件の有効な PDF で失敗します。pypdf は 61 件で失敗します。どちらの場合も、これらはライブラリがクラッシュするか、空または誤ったテキストを返す有効な PDF ファイルです。PDF Oxide は 3,823 件すべての有効な PDF を失敗なく処理します。
3,830 件のフルコーパスのうち合格しなかった 7 件のファイルは、意図的に壊されたテストフィクスチャ(PDF ヘッダーの欠落、ファズ破損したカタログ、無効な xref ストリーム)であり、すべてのライブラリの合格率計算から除外されています。
実際に意味すること
毎日数千件の PDF を処理するパイプラインでは、PyMuPDF の 99.3% という合格率は、1,000 件の文書あたり約 7 件の失敗を意味します。pypdf の 98.4% は 1,000 件あたり 16 件の失敗を意味します。これらは、フォールバックロジック、手動レビューで対処するか、あるいは単に失われたデータとして受け入れる必要がある文書です。
PDF Oxide のテストコーパスにおける 100% の合格率は、本番環境で処理すべきエッジケースが少ないことを意味します。
機能比較
テキスト抽出
3 つのライブラリすべてが基本的なテキスト抽出をサポートしています。API のスタイルは異なります:
PyMuPDF:
import fitz
doc = fitz.open("report.pdf")
page = doc[0]
text = page.get_text()
print(text)
pypdf:
from pypdf import PdfReader
reader = PdfReader("report.pdf")
text = reader.pages[0].extract_text()
print(text)
PDF Oxide:
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
text = doc.extract_text(0)
print(text)
PyMuPDF はページオブジェクトモデルを使用します(doc[0] がページを返します)。pypdf はリーダー / ページのパターンを使用します。PDF Oxide はページインデックスを直接使用します。
文字レベルの抽出(位置、フォントサイズ、バウンディングボックス)について、PyMuPDF はネストされた辞書構造を返す get_text("dict") を提供します。pypdf は部分的な文字位置データを提供します。PDF Oxide は、文字ごとのバウンディングボックスとフォントメタデータを伴う extract_chars() を提供します。
Markdown 変換
これは大きな差別化要因です。多くの LLM および RAG パイプラインは、PDF からの Markdown 出力を必要とします。
PyMuPDF:
# PyMuPDF has no built-in Markdown conversion.
# You need pymupdf4llm, a separate package:
import pymupdf4llm
md = pymupdf4llm.to_markdown("paper.pdf")
pymupdf4llm は機能しますが、PDF Oxide の組み込み Markdown 変換よりも 69 倍遅いです(平均 55.5ms 対 0.8ms)。また、独自のメンテナンスサイクルを持つ別個の依存関係でもあります。
pypdf:
# pypdf has no Markdown conversion.
# You would need an external tool chain (e.g., extract text,
# then use a separate library to structure it as Markdown).
PDF Oxide:
from pdf_oxide import PdfDocument
doc = PdfDocument("paper.pdf")
md = doc.to_markdown(0, detect_headings=True)
print(md)
PDF Oxide の Markdown 変換は組み込みで、見出し検出を処理し、テーブル構造を保持し、プレーンテキスト抽出と同じ速度で動作します。
HTML 変換
PyMuPDF: 組み込みの HTML 出力なし。
pypdf: HTML 出力なし。
PDF Oxide:
from pdf_oxide import PdfDocument
doc = PdfDocument("paper.pdf")
html = doc.to_html(0)
print(html)
フォームフィールド
3 つのライブラリすべてがフォームフィールド(AcroForm)の読み取りと書き込みをサポートしています。
PyMuPDF:
import fitz
doc = fitz.open("form.pdf")
page = doc[0]
for widget in page.widgets():
print(f"{widget.field_name}: {widget.field_value}")
pypdf:
from pypdf import PdfReader
reader = PdfReader("form.pdf")
fields = reader.get_fields()
for name, field in fields.items():
print(f"{name}: {field.get('/V', '')}")
PDF Oxide:
from pdf_oxide import PdfDocument
doc = PdfDocument("form.pdf")
fields = doc.get_form_fields()
for field in fields:
print(f"{field.name}: {field.value}")
注目すべき違いが 1 つあります。PDF Oxide は XFA フォーム(XML Forms Architecture)をサポートしており、これは多くの政府機関や企業の PDF フォームで使用されています。PyMuPDF も pypdf も XFA フォームデータの抽出を処理できません。
画像抽出
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"])
pypdf:
from pypdf import PdfReader
reader = PdfReader("report.pdf")
page = reader.pages[0]
for i, image in enumerate(page.images):
with open(f"image_{i}.{image.name.split('.')[-1]}", "wb") as f:
f.write(image.data)
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"])
3 つすべてが埋め込み画像の抽出を処理します。PyMuPDF のアプローチは 2 段階の xref ルックアップを必要とします。pypdf と PDF Oxide はより洗練された API を提供します。
レンダリング
PyMuPDF は MuPDF のレンダリングエンジンを使用して PDF ページを画像(PNG、JPEG)にレンダリングできます。pypdf はページをまったくレンダリングできません。PDF Oxide には組み込みのレンダリングエンジンが含まれています。
OCR
PyMuPDF はスキャンされた PDF の OCR のために Tesseract と統合します。pypdf には OCR サポートがありません。PDF Oxide は PaddleOCR による組み込み OCR を備えており、外部システム依存を必要としません。
PDF 作成
PyMuPDF は PDF を作成できますが、テキスト、画像、図形をページ上に手動で配置する必要があります。構造化されたコンテンツから PDF を作成するための高レベル API はありません。
pypdf はゼロから PDF を作成できません。既存の PDF の結合、分割、変更はできますが、作成には reportlab や fpdf2 などの別個のライブラリが必要です。
PDF Oxide は Markdown または HTML から PDF を作成できます:
from pdf_oxide import Pdf
pdf = Pdf.from_markdown("# Invoice\n\n| Item | Price |\n|------|-------|\n| Widget | $9.99 |")
pdf.save("invoice.pdf")
暗号化
3 つのライブラリすべてが暗号化された PDF の読み取りと暗号化された出力の書き込みをサポートしています。
PyMuPDF:
import fitz
doc = fitz.open("encrypted.pdf")
doc.authenticate("password")
text = doc[0].get_text()
pypdf:
from pypdf import PdfReader
reader = PdfReader("encrypted.pdf")
reader.decrypt("password")
text = reader.pages[0].extract_text()
PDF Oxide:
from pdf_oxide import PdfDocument
doc = PdfDocument("encrypted.pdf", password="password")
text = doc.extract_text(0)
機能のまとめ
| 機能 | PyMuPDF | pypdf | PDF Oxide |
|---|---|---|---|
| テキスト抽出 | あり | あり | あり |
| 文字位置 | あり | 部分的 | あり |
| 画像抽出 | あり | あり | あり |
| フォームフィールド(AcroForm) | 読み取り + 書き込み | 読み取り + 書き込み | 読み取り + 書き込み |
| XFA フォーム | なし | なし | あり |
| PDF 作成 | 手動 | なし | Markdown / HTML |
| Markdown 出力 | なし(pymupdf4llm) | なし | 組み込み |
| HTML 出力 | なし | なし | 組み込み |
| レンダリング | あり | なし | あり |
| OCR | Tesseract | なし | 組み込み(PaddleOCR) |
| 検索 | あり | なし | 正規表現 + 空間検索 |
| 暗号化 | 読み取り + 書き込み | 読み取り + 書き込み | 読み取り + 書き込み |
| PDF/A 検証 | なし | なし | あり |
| SVG エクスポート | あり | なし | なし |
| 結合 / 分割 | あり | あり | あり |
各ライブラリを選ぶべき場合
pypdf を選ぶべき場合:
- コンパイルされた C や Rust の拡張機能のない純粋な Python ソリューションが必要な場合
- 単純な PDF 操作(結合、分割、回転、暗号化 / 復号)を行っている場合
- ユースケースにおいて速度が重要でない場合
- 可能な限り小さいインストールフットプリント(約 1 MB)を求めている場合
- 幅広い Python バージョンのサポート(3.6+)が必要な場合
PyMuPDF を選ぶべき場合:
- すでに Artifex から MuPDF の商用ライセンスを持っている場合
- PDF ページからの SVG エクスポートが必要な場合
- プロジェクトがすでに AGPL-3.0 でライセンスされている場合
- MuPDF 固有のレンダリング動作に依存している場合
PDF Oxide を選ぶべき場合:
- 最大限のテキスト抽出速度が必要な場合(PyMuPDF より 5.8 倍、pypdf より 15 倍高速)
- 商用またはクローズドソース用途で MIT ライセンスを望む場合
- LLM / RAG パイプライン用の組み込み Markdown または HTML 出力が必要な場合
- XFA フォームのサポートが必要な場合
- 外部システム依存なしの組み込み OCR を望む場合
- 有効な PDF で 100% の信頼性を望む場合
インストール
# PyMuPDF
pip install pymupdf
# pypdf
pip install pypdf
# PDF Oxide
pip install pdf_oxide
3 つすべてが pip 経由で利用できます。PyMuPDF は MuPDF を同梱した約 20 MB のホイールを出荷します。pypdf は約 1 MB の純粋な Python です。PDF Oxide は Linux(x86_64、aarch64)、macOS(x86_64、arm64)、Windows(x86_64)向けにビルド済みホイール(約 5 MB)を出荷します。
結論
PyMuPDF と pypdf のどちらかを選んでいるなら、速度とライセンスの自由のどちらかを選んでいることになります。PDF Oxide は両方を提供します — PyMuPDF より高速で、pypdf より寛容で、どちらのライブラリにもない機能を備えています。
| あなたにとって重要なこと | 最適な選択 |
|---|---|
| 最大限の速度 | PDF Oxide(0.8ms) |
| 寛容なライセンス | PDF Oxide(MIT)または pypdf(BSD) |
| 速度 + 寛容なライセンス | PDF Oxide — 唯一の選択肢 |
| Markdown / HTML 出力 | PDF Oxide — 組み込み |
| XFA フォーム | PDF Oxide — サポートする唯一のライブラリ |
| 100% の信頼性 | PDF Oxide — 100% の合格率 |
| Tesseract なしの OCR | PDF Oxide — 組み込みの PaddleOCR |
| SVG エクスポート | PyMuPDF |
| 純粋な Python、バイナリなし | pypdf |
10 秒で始める:
pip install pdf_oxide
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
text = doc.extract_text(0)
関連ページ
- PDF Oxide vs PyMuPDF — 詳細な比較
- PDF Oxide vs pypdf — 詳細な比較
- すべての Python PDF ライブラリとの比較 — エコシステム全体の比較
- パフォーマンスベンチマーク — 手法と結果