Skip to content

PyMuPDF (fitz)에서 PDF Oxide로 마이그레이션

PyMuPDF에서 PDF Oxide로 전환하는 전체 가이드입니다. 현재 사용 중인 모든 API와 이를 어떻게 대체할 수 있는지 다룹니다.

왜 PyMuPDF에서 옮겨야 할까

이전할 만한 네 가지 뚜렷한 이유가 있습니다.

  1. 5.8× 빠름 — PDF Oxide는 페이지당 평균 0.8ms, PyMuPDF는 4.6ms입니다. 규모가 커질수록 차이는 누적되어 1,000페이지 배치가 5초가 아니라 1초 이내에 끝납니다.
  2. MIT 라이선스 — PyMuPDF는 AGPL이라서 상호작용하는 모든 코드를 공개하거나 상업 라이선스를 구입해야 합니다. PDF Oxide는 MIT라서 제약 없이 어디서든 사용할 수 있습니다.
  3. 100% 안정성 — PDF Oxide는 PDF 테스트 스위트를 100% 통과합니다. PyMuPDF는 파일의 0.7%에서 실패(성공률 99.3%)하며, 약 140건당 1건꼴로 잘못된 출력이 발생합니다.
  4. 풍부한 기본 기능 — Markdown 변환, HTML 출력, OCR, XFA 폼 지원, PDF 렌더링이 기본 포함됩니다. PyMuPDF에서 비슷한 기능을 쓰려면 별도 패키지(pymupdf4llm)나 외부 도구(Tesseract)가 필요합니다.

1단계: 설치

pip install pdf_oxide
pip uninstall pymupdf  # 선택 — 준비가 되면 제거합니다

2단계: 임포트 교체

# Before
import fitz

# After
from pdf_oxide import PdfDocument

Markdown 변환을 위해 pymupdf4llm을 사용하고 있었다면 해당 의존성은 전부 제거해도 됩니다. PDF Oxide가 기본 지원합니다.

3단계: API 매핑

작업 PyMuPDF PDF Oxide
PDF 열기 fitz.open("file.pdf") PdfDocument("file.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")
폼 필드 doc[0].widgets() 또는 doc.get_form_fields() doc.get_form_fields()
암호화된 PDF doc.authenticate("pw") PdfDocument("f.pdf", password="pw")
Markdown 변환 pymupdf4llm.to_markdown("file.pdf")(별도 패키지) doc.to_markdown(0)(내장)
HTML 변환 미지원 doc.to_html(0)
PDF 생성 insert_text()를 수동으로 사용 Pdf.from_markdown("# Title")
이미지로 렌더링 doc[0].get_pixmap() doc.render_page(0)
XFA 폼 미지원 doc.has_xfa()
OCR Tesseract 필요 PaddleOCR 내장

4단계: 자주 쓰이는 패턴 변경

텍스트 추출 루프

# PyMuPDF
import fitz
doc = fitz.open("report.pdf")
for page in doc:
    text = page.get_text()
    print(text)

# PDF Oxide
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
for i in range(doc.page_count()):
    text = doc.extract_text(i)
    print(text)

이미지 추출

PyMuPDF는 여러 단계의 xref 조회가 필요합니다. PDF Oxide는 단 한 번의 호출로 처리합니다.

# PyMuPDF — 여러 단계의 xref 조회
import fitz
doc = fitz.open("report.pdf")
page = doc[0]
for img in page.get_images():
    xref = img[0]
    base = doc.extract_image(xref)
    with open(f"img.{base['ext']}", "wb") as f:
        f.write(base["image"])

# PDF Oxide — 한 단계
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
for i, img in enumerate(doc.extract_image_bytes(0)):
    with open(f"img_{i}.{img['format']}", "wb") as f:
        f.write(img["data"])

암호화된 PDF

PyMuPDF는 "열고 나서 인증"하는 두 단계 패턴을 사용합니다. PDF Oxide는 생성자에서 password=를 전달하는 방식과 열람 후 doc.authenticate()를 호출하는 방식을 모두 지원합니다.

# PyMuPDF
import fitz
doc = fitz.open("encrypted.pdf")
doc.authenticate("password")
text = doc[0].get_text()

# PDF Oxide — password= 한 단계
from pdf_oxide import PdfDocument
doc = PdfDocument("encrypted.pdf", password="password")
text = doc.extract_text(0)

Markdown 변환

PyMuPDF는 별도의 pymupdf4llm 패키지를 요구합니다. PDF Oxide는 Markdown을 내장하고 있습니다.

# PyMuPDF — 별도 패키지 필요
import pymupdf4llm
md = pymupdf4llm.to_markdown("report.pdf")

# PDF Oxide — 내장 기능
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
md = doc.to_markdown(0)

페이지 렌더링

# PyMuPDF
import fitz
doc = fitz.open("report.pdf")
pix = doc[0].get_pixmap()
pix.save("page.png")

# PDF Oxide
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
png_bytes = doc.render_page(0, dpi=150)
with open("page.png", "wb") as f:
    f.write(png_bytes)

5단계: 마이그레이션 테스트

기존 테스트 파일을 두 라이브러리에 각각 실행해 출력을 비교합니다.

from pdf_oxide import PdfDocument

doc = PdfDocument("your-test-file.pdf")

# 텍스트 추출 확인
text = doc.extract_text(0)
print(text[:500])

# 페이지 수 확인
print(f"Pages: {doc.page_count()}")

# 폼 필드 확인(해당되는 경우)
fields = doc.get_form_fields()
for f in fields:
    print(f"{f.name}: {f.value}")

기타 마이그레이션 가이드

관련 페이지