PyMuPDF vs pypdf — どちらの Python PDF ライブラリを選ぶべきか?
PyMuPDF と pypdf は Python で最も人気のある PDF ライブラリですが、どちらにも大きなトレードオフがあります。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) | Pure 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 vs BSD vs MIT
PyMuPDF と pypdf の間のライセンスの違いが、チームが両者を選ぶ際の決定的要因になることが多いです。
PyMuPDF — AGPL-3.0
PyMuPDF は AGPL-3.0 ライセンスの MuPDF をラップしています。これは強いコピーレフトライセンスです。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 ライセンスで、パーミッシブです。商用製品、クローズドソフトウェア、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 はパース、フォントデコード、テキスト組み立てのすべてを Pure 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 はコーパスの有効 PDF のうち 27 件で失敗します。pypdf は 61 件で失敗します。どちらの場合も、ライブラリがクラッシュするか、空/不正なテキストを返す有効な PDF ファイルです。PDF Oxide は 3,823 件の有効な PDF すべてを問題なく処理します。
3,830 ファイルコーパスのうちパスしない 7 ファイルは、意図的に壊されたテストフィクスチャ(PDF ヘッダーの欠落、ファジングで破損したカタログ、無効な xref ストリーム)で、すべてのライブラリのパス率計算から除外されています。
実運用での意味
1 日に数千の 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 は入れ子の dict 構造を返す get_text("dict") を提供します。pypdf は部分的な文字位置データを提供します。PDF Oxide は文字ごとのバウンディングボックスとフォントメタデータを含む extract_chars() を提供します。
Markdown 変換
多くの LLM や RAG パイプラインが PDF から Markdown 出力を必要としており、ここが大きな差別化ポイントです。
PyMuPDF:
# PyMuPDF には内蔵の Markdown 変換がありません。
# 別パッケージ pymupdf4llm が必要:
import pymupdf4llm
md = pymupdf4llm.to_markdown("paper.pdf")
pymupdf4llm は動作しますが、PDF Oxide の内蔵 Markdown 変換の 69 倍遅い(平均 55.5ms vs 0.8ms)です。独自のメンテナンスサイクルを持つ別の依存パッケージでもあります。
pypdf:
# pypdf には Markdown 変換機能がありません。
# 外部ツールチェーンが必要です(テキスト抽出後、
# 別のライブラリで 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}")
注目すべき違い: 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 を内蔵しており、外部システム依存パッケージは不要です。
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 拡張を含まない Pure 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 の wheel を提供します。pypdf は ~1 MB の Pure Python です。PDF Oxide は Linux(x86_64, aarch64)、macOS(x86_64, arm64)、Windows(x86_64)向けのビルド済み wheel(~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 |
| Pure 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 ライブラリとの比較 — 全エコシステムの比較
- パフォーマンスベンチマーク — 手法と結果