python Pymupdf和Acrobat Reader的“deflate”参数出现问题

0qx6xfy6  于 2022-12-10  发布在  Python
关注(0)|答案(1)|浏览(204)

我的程序正在密文PDF文件中的敏感信息。在保存密文PDF时,我传递了几个参数以避免导出过大的文件:

doc.save(
    file_path,
    permissions=fitz.PDF_PERM_PRINT, 
    owner_pw="owner",
    encryption=fitz.PDF_ENCRYPT_AES_256,
    garbage=3, 
    deflate=True
)

这些PDF文件旨在通过Adobe Acrobat Reader(版本2021.007.20099)打开。

**问题是:**当我使用Acrobat打开密文文件时,某些文件弹出一个窗口,显示以下消息:

An error exists on this page. Acrobat may not display the page correctly. 
Please contact the person who created the PDF document to correct the problem.

如果单击OK按钮关闭警告消息,则可以浏览文件而不会出现任何可见问题。
如何删除此警告消息?

在调试时我意识到当我传递deflate=False作为参数时问题就解决了。但这不是一个可行的解决方案,因为编辑后的文件大小有时比原始文件大10倍。

下面是official documentationdeflate的说明:

deflate (bool) – Deflate (compress) uncompressed streams.

garbage参数似乎对该问题没有影响,其余参数对该过程至关重要,因此无法更改。
这可能是密文重叠的问题(在相同的x,y坐标上应用多次),但其中一些情况不会引发错误。
如果你能帮上忙,我会很感激的。谢谢。

重现错误:

可以使用以下命令重现该错误:
python redact_pdf.py test_file.pdf

  • redact_pdf.py:要启动的脚本(请参阅下文)
  • test_file.pdf:要密文的PDF文件-〉test_file.pdf
  • 注意:两个文件必须位于同一目录中 *
    编辑_pdf.py
import sys
import fitz

def redact_pdf(file_path: str) -> None:
    """
    This file redacts all text "blocks" containing "XX" by deleting the initial text
    and covering its surface (bounding box) with a black rectangle. The redacted PDF
    file is named and exported as follows : "file_path_ANON.pdf"

    Args:
        file_path: path to the file to redact, passed as a command line parameter

    Returns:
        None
    """
    try:
        doc = fitz.open(file_path)
        redacted = False

        for page in doc:
            page.wrap_contents()
            blocks = page.get_text("blocks")

            for block in blocks:
                if "XX" in block[4]:
                    page.add_redact_annot(block[:4], fill=(0, 0, 0))
                    if page.apply_redactions(images=fitz.PDF_REDACT_IMAGE_REMOVE):
                        redacted = True

        if redacted:
            file_path = file_path.replace(".pdf", "_ANON.pdf")
            doc.save(
                file_path,
                permissions=fitz.PDF_PERM_PRINT,
                owner_pw="owner",
                encryption=fitz.PDF_ENCRYPT_AES_256,
                garbage=4,
                deflate=True
            )
            print("Redacted file :", file_path)
        else:
            print("No redaction detected")

    except BaseException as err:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        print(f"{type(err)} (line {exc_tb.tb_lineno}) : {err}")

if __name__ == "__main__":
    redact_pdf(sys.argv[1])

在我的例子中,这会导致corrupted file在使用Acrobat Reader打开时引发之前引用的警告消息。
请注意,在浏览器中打开文件不会引发警告消息。不幸的是,我无法更改PDF打开的默认行为,因此我必须坚持使用Acrobat Reader。
Link to Github issue

xwbd5t1u

xwbd5t1u1#

根据Jorj McKie的注解并根据相关的github issue
该问题在PyMuPDF的最新版本1.21.0中不再出现。
但是,虽然Adobe Acrobat中可能不再有警告,但查看此处的文件会发现original file的内容流中已经存在错误,redacted file中的内容流中甚至存在更多错误。
这些错误有两种类型:

  • 在文本对象外使用文本定位指令无效。
  • 路径定义和路径绘制指令之间的颜色设置指令的使用无效。

(可能还有其他错误,但这两种类型真的让我很吃惊。)
例如,原始文件和密文文件各自的第一个内容流如下所示:

q
.1 w
0 .1 595.3 841.9 re
W*
n
q
/F1 10 Tf
1 0 0 1 311.9 693.5 Tm
Q
q
/F1 10 Tf
1 0 0 1 349.7 693.5 Tm
Q
...

此处,Tm指令用于文本对象之外,这是不允许的,参见ISO 32000的 * 图9 -图形对象 *。
在编辑文件的内容流中添加了以下内容块:

258.8 313.181 37.2084 7.17188 re
h
1 1 1 rg
1 1 1 RG
B

这里,在路径构造和路径绘制操作符之间使用了颜色指令,这也是不允许的,请参见上面引用的同一张图。
一般的检视器似乎对这些错误相当松懈(例如Acrobat不会抱怨原始档案中的问题),但它们仍然是错误,而且最终可能会造成问题。

相关问题