PyMuPDF로 PDF 페이지의 일부를 이미지로 갈무리하기

Twitter icon류광, 2022-07-23 21:07
PyMuPDF를 이용해서 PDF 페이지의 일부를 이미지로 갈무리해서 저장하는 방법.

PDF 파일의 특정 페이지의 특정 영역을 이미지로 갈무리해서 이미지 파일로 저장할 일이 있는데, PyMuPDF가 괜찮아 보여서 조금씩 공부하고 있습니다. 이름에서 짐작하듯이 PyMuPDF는 파이썬 라이브러리로, 유명한 PDF 뷰어/도구 모음/라이브러리인 MuPDF의 파이썬 바인딩입니다.

PDF 파일에 내장된 이미지 파일들을 자동으로 추출해 주는 방법은 여러 가지이지만, 이미지 위에 텍스트가 겹쳐진 경우에는 이미지 파일만 추출하는 것으로 부족합니다. 예를 들어 개발서, 특히 번역서의 '그림(figure)'은 원서 이미지 위에 한글 텍스트를 얹은 형태인 경우가 꽤 있습니다. 그런 경우 그림 부분을 이미지 파일로 저장하려면, 페이지 전체를 이미지로 렌더링하고 그림 부분을 따로 저장하는 게 제일 간단한 방법이 아닐까 합니다.

각설하고, 다음은 PyMuPDF를 이용해서 PDF 파일의 특정 페이지의 특정 직사각형 영역을 이미지 파일로 저장하는 방법을 보여주는 파이썬 코드입니다.

import fitz

# 렌더링할 페이지 번호. 0부터 시작.
pnum = 123  

# PDF 파일을 열고 원하는 페이지를 적재
doc = fitz.open("test.pdf")
page = doc.load_page(pnum)

# PDF 가장자리 인쇄용 영역을 제외한 실제 페이지만 보이도록 설정
page.set_cropbox(page.mediabox)

scale = 2  # 확대축소 비율(더 높은 해상도를 위해)

# 갈무리할 영역의 너비, 높이, 시작점 x, y
# 페이지 좌측 상단이 (0, 0)
w, h, x, y = 500, 400, 100, 200 

# 확대축소 비율에 맞게 너비 등을 비례
width  = int(w * scale)
height = int(h * scale)
left = int(x * scale)
top = int(y * scale)

# 페이지를 픽셀맵으로 렌더링.
pix = page.get_pixmap(matrix=fitz.Matrix(scale, scale), anots=False)

# 페이지 일부 영역을 갈무리해서 저장할 빈 픽셀맵 생성
newpix = fitz.Pixmap(fitz.csRGB, (0, 0, width, height), False)

# 갈무리할 영역의 왼쪽 상단 모서리가 페이지 좌표계의 
# 원점이 되도록 좌표계를 이동한다--이 부분이 핵심!
pix.set_origin(-left, -top)

# 이제 그 지점부터 너비, 높이만큼 새 픽셀맵에 복사
newpix.copy(pix, (0, 0, width, height))

# 마지막으로 파일로 저장
newpix.save("captured.png")

set_origin으로 좌표계를 옮겨서 원하는 영역을 지정하는 기법은 PyMuPDF 문서화 pixmap.copy 항목의 Notes에 나와 있습니다. 처음에는 그냥

# 이렇게 하면 안 됨!!
newpix.copy(pix, (left, top, left+width-1, top+height-1))

로 했는데, 엉뚱한 부분이 갈무리되어서 한참 헤맸네요.

태그: 프로그래밍 파이썬 PDF

comments powered by Disqus