pymupdf からの移行¶
pylopdf は pymupdf「風」であって、ドロップイン互換ではありません。ただし移行
コストを決めるデータ形状 — "words" タプルの並び・"dict" の構造・
search_for → list[Rect]・TOC の 1 始まりページ番号 — は pymupdf に合わせて
いるため、抽出やページ操作のコードは小さな修正で移植できます。このページでは
「そのまま動くもの」「変わったもの」「あえて実装せず連携で解決するもの」を
まとめます。
Note
pylopdf が扱うのは PDF のみです。pymupdf の XPS / EPUB / 画像を開く 機能は対象外です。
対応表¶
| pymupdf | pylopdf | 備考 |
|---|---|---|
import fitz / import pymupdf |
import pylopdf |
|
fitz.open(path) / open(stream=…) |
pylopdf.open(path) / open(stream=…) |
password= も同じ |
doc[i]・len(doc)・イテレーション |
同じ | 0 始まり・負数可 |
doc.metadata / set_metadata |
同じ | キー名も同じ |
page.get_text() |
同じ | オプションは text / words / blocks / dict |
page.search_for(t) |
同じ | list[Rect]。quads= は無い |
page.get_pixmap(matrix=fitz.Matrix(2, 2)) |
page.get_pixmap(scale=2) |
dpi=144 でも。Matrix クラスは無い |
pix.samples / width / height / stride |
同じ | 常にストレートアルファ RGBA8。tobytes() → PNG |
page.get_images() |
page.get_images() |
描画位置 bbox 付き。JPEG はパススルー |
doc.select・delete_page(s)・copy_page・new_page |
同じ | select の重複指定は複製になる |
doc.insert_pdf(src, from_page=, to_page=, start_at=) |
同じ | |
doc.get_toc() / set_toc() |
同じ | ページ番号は両者とも 1 始まり |
doc.save(garbage=4, deflate=True) |
doc.save(garbage=True, deflate=True, object_streams=True) |
garbage は bool |
doc.save(encryption=…, user_pw=…) |
doc.save(user_pw=…, owner_pw=…, permissions=…) |
AES-256 のみ |
doc.needs_pass / authenticate() |
同じ | 戻り値の意味(0/1/2/4/6)も同じ |
page.rect / rotation / set_rotation |
同じ | |
page.insert_image(rect, filename=) |
同じ | JPEG/PNG のみ。pixmap= は無い(他形式は Pillow で変換) |
page.show_pdf_page(rect, src, pno) |
同じ | 同一ドキュメントの重ねは不可(複製してから) |
page.insert_text(point, text, fontsize=, fontname=, fontfile=) |
同じ。加えて fontbuffer= / fontindex= |
フォント指定なしは標準 14 / WinAnsi。指定時は HarfRust で字形処理し krilla でサブセット埋め込み |
page.insert_textbox(rect, text, align=, lineheight=) |
同じ。任意の fontfile= / fontbuffer= に対応 |
UAX #14 の CJK 折り返し。負の戻り値なら描画しない |
page.add_highlight_annot(...) |
同じ | 外観ストリームを常に生成 |
doc.embfile_add / names / get / del |
同じ | |
doc.get_page_labels / set_page_labels・page.get_label |
同じ | |
page.widgets() / Widget オブジェクト |
doc.get_form_fields() / doc.set_form_field(name, value, fontfile=) |
ドキュメント単位。テキスト/選択/checkbox/radioのネイティブ外観 |
pymupdf4llm.to_markdown(doc) |
doc.to_markdown() |
内蔵・MIT |
挙動の違い¶
- 座標系はどちらも左上原点の表示空間。pylopdf では回転ページでも 抽出・検索・描き込み・レンダリングが一貫して同じ座標になります。
- 型:
Rectは不変のNamedTuple(x0, y0, x1, y1+width/height)。Point/Matrix/Quadクラスは無く、API は素のタプルとscale=/dpi=を受けます。 - 古い Page: 構造変更(削除・挿入・並べ替え)後に古い
Pageを使うと、 黙って別ページを指す代わりにStalePageErrorになります。doc[i]で 取得し直してください。 - 例外: 基底は
PdfError(ValueErrorのサブクラス)。PasswordError/DocumentClosedError/EncryptedDocumentError/StalePageErrorが それを細分化します。except ValueErrorは動き続けます。 get_textのオプションはtext/words/blocks/dictのみ (html/rawdict/xmlは無し)。スパン辞書は埋め込みフォントについてfontと pymupdf 互換のflags(bold/italic/serif/mono)を持ちます。- 複数カラムのテキストは、決定的な空白ガター検出により、各カラム内を 上から下へ、カラム間を左から右へ読みます。
Page.find_tables()は線または細い塗り矩形から軸平行の罫線グリッドを 再構築し、矩形の結合セルにも対応します。strategy="text"を指定すると、 高信頼な罫線なし表を検出します(整列した複数カラム本文との幾何的な曖昧さは 残ります)。既知の表示座標領域に完全に収まる表だけを返すにはclip=を使い、 罫線なし結果の順位付けにはTable.confidence/Table.diagnosticsを確認します。- フォーム記入は値とネイティブ外観を書き込み、pylopdfと外部ビューアの両方で
描画されます。WinAnsiはHelveticaで自動縮小され、UnicodeはOpenTypeフォントを
指定するか
pylopdf[cjk]を導入します。リッチテキスト、comb配置、pushbutton、 署名は対象外です。 - CJK 縦書きは保守的に検出し、列内を上から下、列間を右から左へ読みます。 ルビ、割注、縦中横などの混在組版は解釈しません。
あえて実装しないもの — エコシステムで解決¶
| pymupdf の機能 | pylopdf での答え |
|---|---|
Story API / insert_htmlbox(組版) |
typst(typst-py 経由)— レシピ |
OCR(get_textpage_ocr。Tesseract の外部インストール必須) |
任意の OCR エンジン + insert_ocr_text_layer |
| 電子署名 | pyHanko(MIT)— レシピ |
| インクリメンタル保存 | 非対応の方針(qpdf/pikepdf と同じ書き直し思想)。署名用途は pyHanko が担う |
| XPS / EPUB / CBZ / 画像を開く | 対象外 — PDF 専用 |