일반적인 문제 및 해결 방법

손상된 PDF 를 동적으로 정리하는 방법

이것은 다른 Python PDF 라이브러리와 함께 PyMuPDF 를 사용하는 잠재적 사용 사례를 보여줍니다(여기서는 우수한 순수 Python 패키지 pdfrw 를 예제로 사용합니다).

깨끗하고 손상되지 않은/압축 해제된 PDF가 필요한 경우, 다음과 같이 PyMuPDF 를 동적으로 호출하여 많은 문제에서 복구할 수 있습니다:

import sys
from io import BytesIO
from pdfrw import PdfReader
import pymupdf

#---------------------------------------
# 'Tolerant' PDF reader
#---------------------------------------
def reader(fname, password = None):
    idata = open(fname, "rb").read()  # read the PDF into memory and
    ibuffer = BytesIO(idata)  # convert to stream
    if password is None:
        try:
            return PdfReader(ibuffer)  # if this works: fine!
        except:
            pass

    # either we need a password or it is a problem-PDF
    # create a repaired / decompressed / decrypted version
    doc = pymupdf.open("pdf", ibuffer)
    if password is not None:  # decrypt if password provided
        rc = doc.authenticate(password)
        if not rc > 0:
            raise ValueError("wrong password")
    c = doc.tobytes(garbage=3, deflate=True)
    del doc  # close & delete doc
    return PdfReader(BytesIO(c))  # let pdfrw retry
#---------------------------------------
# Main program
#---------------------------------------
pdf = reader("pymupdf.pdf", password = None) # include a password if necessary
print pdf.Info
# do further processing

명령줄 유틸리티 pdftk (available 는 Windows 전용이지만 Wine 에서도 실행된다고 보고됨)를 사용하여 유사한 결과를 얻을 수 있습니다. 자세한 내용은 here 를 참조하세요. 하지만 stdin과 stdout을 통신 수단으로 사용하여 subprocess.Popen 을 통해 별도 프로세스로 호출해야 합니다.

모든 문서를 PDF 로 변환하는 방법

다음은 PyMuPDF지원하는 문서PDF 로 변환하는 스크립트입니다. 여기에는 XPS, EPUB, FB2, CBZ 및 다중 페이지 TIFF 이미지를 포함한 이미지 형식이 포함됩니다.

소스 문서에 포함된 모든 메타데이터, 목차 및 링크를 유지하는 기능이 있습니다:

"""
Demo script: Convert input file to a PDF
-----------------------------------------
Intended for multi-page input files like XPS, EPUB etc.

Features:
---------
Recovery of table of contents and links of input file.
While this works well for bookmarks (outlines, table of contents),
links will only work if they are not of type "LINK_NAMED".
This link type is skipped by the script.

For XPS and EPUB input, internal links however **are** of type "LINK_NAMED".
Base library MuPDF does not resolve them to page numbers.

So, for anyone expert enough to know the internal structure of these
document types, can further interpret and resolve these link types.

Dependencies
--------------
PyMuPDF v1.14.0+
"""
import sys
import pymupdf
if not (list(map(int, pymupdf.VersionBind.split("."))) >= [1,14,0]):
    raise SystemExit("need PyMuPDF v1.14.0+")
fn = sys.argv[1]

print(f"Converting '{fn}' to '{fn}.pdf'")

doc = pymupdf.open(fn)

b = doc.convert_to_pdf()  # convert to pdf
pdf = pymupdf.open("pdf", b)  # open as pdf

toc= doc.get_toc()  # table of contents of input
pdf.set_toc(toc)  # simply set it for output
meta = doc.metadata  # read and set metadata
if not meta["producer"]:
    meta["producer"] = "PyMuPDF v" + pymupdf.VersionBind

if not meta["creator"]:
    meta["creator"] = "PyMuPDF PDF converter"
meta["modDate"] = pymupdf.get_pdf_now()
meta["creationDate"] = meta["modDate"]
pdf.set_metadata(meta)

# now process the links
link_cnti = 0
link_skip = 0
for pinput in doc:  # iterate through input pages
    links = pinput.get_links()  # get list of links
    link_cnti += len(links)  # count how many
    pout = pdf[pinput.number]  # read corresp. output page
    for l in links:  # iterate though the links
        if l["kind"] == pymupdf.LINK_NAMED:  # we do not handle named links
            print("named link page", pinput.number, l)
            link_skip += 1  # count them
            continue
        pout.insert_link(l)  # simply output the others

# save the conversion result
pdf.save(fn + ".pdf", garbage=4, deflate=True)
# say how many named links we skipped
if link_cnti > 0:
    print(f"Skipped {link_skip} named links of a total of {link_cnti} in input.")

주석 변경: 예상치 못한 동작

문제

두 가지 시나리오가 있습니다:

  1. 다른 소프트웨어로 생성된 주석을 PyMuPDF업데이트 하는 경우.

  2. PyMuPDF 로 주석을 생성 한 후 다른 소프트웨어로 변경하는 경우.

두 경우 모두 주석 아이콘이나 텍스트 글꼴이 다르게 표시되거나, 채우기 색상이나 선의 파선이 사라지거나, 선 끝 기호의 크기가 변경되거나 사라지는 등의 의도하지 않은 변경이 발생할 수 있습니다.

원인

주석 유지 관리는 각 PDF 유지 관리 애플리케이션마다 다르게 처리됩니다. 일부 주석 유형은 지원되지 않거나 완전히 지원되지 않을 수 있으며, 일부 세부 사항은 다른 애플리케이션과 다른 방식으로 처리될 수 있습니다. 표준이 없습니다.

거의 항상 PDF 애플리케이션은 자체 아이콘(파일 첨부, 스티커 메모 및 스탬프)과 자체 지원 텍스트 글꼴 세트를 제공합니다. 예를 들어:

  • (Py-) MuPDF 는 ‘FreeText’ 주석에 대해 다음 5가지 기본 글꼴만 지원합니다: Helvetica, Times-Roman, Courier, ZapfDingbats 및 Symbol – 기울임꼴/굵게 변형 없음. 다른 앱으로 생성된 ‘FreeText’ 주석을 변경할 때 해당 글꼴은 인식되지 않거나 허용되지 않을 가능성이 높으며 Helvetica로 대체됩니다.

  • PyMuPDF 는 모든 PDF 텍스트 마커(강조, 밑줄, 취소선, 물결선)를 지원하지만, 이러한 유형은 Adobe Acrobat Reader로 업데이트할 수 없습니다.

대부분의 경우 선 파선에 대한 제한적인 지원이 있어 기존 파선이 직선으로 대체됩니다. 예를 들어:

  • PyMuPDF 는 모든 선 파선 형식을 완전히 지원하지만, 다른 뷰어는 제한된 하위 집합만 허용합니다.

해결 방법

안타깝게도 대부분의 경우 할 수 있는 일이 많지 않습니다.

  1. 주석을 생성하고 변경 할 때 동일한 소프트웨어를 사용하세요.

  2. “외부” 주석을 변경할 때 PyMuPDF 를 사용하는 경우 Annot.update()피하세요. 다음 메서드는 이것 없이 사용할 수 있으며, 원래 모양이 유지됩니다:

누락되거나 읽을 수 없는 추출된 텍스트

텍스트 추출이 예상대로 작동하지 않는 경우가 많습니다: 텍스트가 누락되거나 화면에 표시되는 읽기 순서에 나타나지 않거나 문자 깨짐(예: ? 또는 “TOFU” 기호)이 포함될 수 있습니다. 이것은 여러 다른 문제로 인해 발생할 수 있습니다.

문제: 텍스트가 추출되지 않음

PDF 뷰어는 텍스트를 표시하지만 커서로 선택할 수 없고 텍스트 추출 결과가 없습니다.

원인

  1. PDF 페이지에 포함된 이미지를 보고 있을 수 있습니다(예: 스캔된 PDF).

  2. PDF 작성자가 글꼴을 사용하지 않고 작은 선과 곡선을 사용하여 텍스트를 시뮬레이션 했습니다. 예를 들어 대문자 “D”는 선 “|”와 왼쪽 열린 반원으로 그려질 수 있고, “o”는 타원으로 그려질 수 있습니다.

해결 방법

OCRmyPDF 와 같은 OCR 소프트웨어를 사용하여 표시되는 페이지 아래에 숨겨진 텍스트 레이어를 삽입하세요. 결과 PDF는 예상대로 작동해야 합니다.

문제: 읽을 수 없는 텍스트

텍스트 추출이 읽을 수 있는 순서로 텍스트를 제공하지 않거나, 일부 텍스트가 중복되거나, 그렇지 않으면 문자 깨짐이 발생합니다.

원인

  1. 개별 문자는 읽을 수 있지만( “<?>” 기호 없음), 텍스트가 파일에 인코딩된 순서가 읽기 순서와 다릅니다. 그 배경에는 기술적 이유나 원치 않는 복사로부터 데이터를 보호하려는 의도가 있을 수 있습니다.

  2. 많은 “<?>” 기호가 발생하여 MuPDF 가 이러한 문자를 해석할 수 없음을 나타냅니다. 글꼴이 실제로 MuPDF 에서 지원되지 않을 수 있거나, PDF 작성자가 읽을 수 있는 텍스트를 표시하지만 의도적으로 원본 해당 유니코드 문자를 난독화하는 글꼴을 사용했을 수 있습니다.

해결 방법

  1. 레이아웃을 유지하는 텍스트 추출을 사용하세요: python -m fitz gettext file.pdf.

  2. 다른 텍스트 추출 도구도 작동하지 않으면, 다시 유일한 해결책은 페이지를 OCR 처리하는 것입니다.

This software is provided AS-IS with no warranty, either express or implied. This software is distributed under license and may not be copied, modified or distributed except as expressly authorized under the terms of that license. Refer to licensing information at artifex.com or contact Artifex Software Inc., 39 Mesa Street, Suite 108A, San Francisco CA 94129, United States for further information.