fitz는 PyMuPDF 라이브러리의 내부 모듈 이름입니다. 설치할 때 이름과 import할 때 이름이 달라서 처음엔 헷갈립니다.
# 설치는 pymupdf로
pip install pymupdf
# import는 fitz로
import fitz
이름이 다른 이유는 MuPDF라는 C 라이브러리를 Python으로 감싼 거라 역사적인 이유로 이름이 굳어졌습니다. "pymupdf = fitz" 로 외우면 됩니다.
doc = fitz.open("파일경로.pdf")
PDF 파일을 열어서 페이지별로 접근할 수 있는 객체를 반환합니다.
len(doc) # 전체 페이지 수
doc[0] # 첫 번째 페이지 (0-indexed)
doc[1] # 두 번째 페이지
pathlib.Path 객체를 쓰고 있다면 str()로 변환해서 넘겨야 합니다.
from pathlib import Path
pdf_path = Path("파일경로.pdf")
doc = fitz.open(str(pdf_path)) # str() 변환 필요
page = doc[0]
text = page.get_text()
print(text)
텍스트 레이어가 있는 PDF는 바로 추출되고, 이미지 기반 PDF는 빈 문자열이 반환됩니다.
텍스트 레이어 존재 여부 판별
if page.get_text().strip():
print("텍스트 레이어 있음")
else:
print("이미지 기반 페이지 → OCR 필요")
.strip()을 붙이는 이유는 공백만 있는 경우를 걸러내기 위해서입니다.
PDF 페이지를 이미지(픽셀 데이터)로 변환합니다. OCR을 돌리거나 PNG로 저장할 때 씁니다.
page = doc[0]
mat = page.get_pixmap(dpi=200) # DPI 200으로 이미지 변환
DPI란?
Dots Per Inch — 1인치에 점을 몇 개 찍을지를 결정하는 해상도 단위입니다. 숫자가 높을수록 선명하지만 처리 속도가 느려집니다.
| DPI | 품질 | 속도 |
|---|---|---|
| 72 | 흐릿함 | 빠름 |
| 150 | 적당 | 보통 |
| 200 | 권장 | 보통 |
| 300 | 선명 | 느림 |
PNG 파일로 저장
mat = page.get_pixmap(dpi=200)
mat.save("page.png")
메모리에서 바로 PIL Image로 변환 (파일 저장 없이)
from PIL import Image
import io
mat = page.get_pixmap(dpi=200)
img = Image.open(io.BytesIO(mat.tobytes("png")))
파일로 저장하지 않고 메모리에서 처리해서 I/O 없이 빠르게 동작합니다.
import fitz
from pathlib import Path
def is_image_based(pdf_path: Path, sample_pages: int = 3) -> bool:
doc = fitz.open(str(pdf_path))
for i in range(min(sample_pages, len(doc))):
if doc[i].get_text().strip():
return False # 텍스트 한 글자라도 나오면 → 텍스트 레이어 있음
return True # 끝까지 텍스트 없으면 → 이미지 기반
min(sample_pages, len(doc))을 쓰는 이유는 PDF가 2페이지짜리인데 sample_pages=3이면 범위 오류가 나기 때문입니다.
| 기능 | 코드 |
|---|---|
| PDF 열기 | fitz.open("path.pdf") |
| 전체 페이지 수 | len(doc) |
| 페이지 접근 | doc[0] |
| 텍스트 추출 | page.get_text() |
| 이미지 변환 | page.get_pixmap(dpi=200) |
| PNG 저장 | mat.save("page.png") |
한 줄 요약:
fitz는 pymupdf의 import 이름이며, PDF를 열어 텍스트 추출·이미지 변환 등 페이지 단위 작업을 처리할 때 씁니다.