如何从 PDF 中删除元数据字段(例如,PageLabel 字段)?

Posted

技术标签:

【中文标题】如何从 PDF 中删除元数据字段(例如,PageLabel 字段)?【英文标题】:How can I drop metadata fields (e.g., PageLabel fields) from PDFs? 【发布时间】:2014-08-28 09:06:53 【问题描述】:

我已使用 pdftk 更改与 PDF 关联的“信息”元数据。我目前有几个带有无关页面标签的 PDF,我不知道如何删除它们。这就是我目前正在做的事情:

$ pdftk example_orig.pdf dump_data output page_labels.orig
$ grep -v PageLabel page_labels.orig > page_labels.new
$ pdftk example_orig.pdf update_info page_labels.new output example_new.pdf

这不会删除可以通过以下方式验证的PageLabel* 元数据:

$ pdftk example_orig.pdf dump_data | grep PageLabel

如何以编程方式从 PDF 中删除此元数据?使用 pdftk 会很好,但如果在 GNU/Linux 上有其他工具或方法可以做到这一点,那也对我有用。

我需要这个,因为我正在使用 LaTeX Beamer 生成带有 \setbeameroptionshow notes on second screen 选项的演示文稿,该选项会生成一个双宽 PDF 以在第二个屏幕上显示笔记。不幸的是,似乎有a bug in pgfpages 导致这些文件(example)中的PageLabels 不正确和无关。如果我生成仅幻灯片 PDF,它将生成正确的 PageLabels (example)。由于我可以生成一组正确的 PageLabels,因此一种解决方案是将第一个示例中的页面标签替换为第二个示例中的页面标签。也就是说,由于第一个示例中有额外的页面标签,我需要先删除它们。

【问题讨论】:

查看您的示例 PDF 将极大地帮助您了解您的 PageLabels 究竟有什么问题/无关紧要,并按照此提供有效的解决方案... 感谢您的反馈@KurtPfeifle。我已经包含了不正确和正确的 PageLabels 示例,并描述了我如何构建这些 PDF。正确的 PageLabels 很重要,因为它们被用作我正在使用的演示软件的提示。 【参考方案1】:

使用文本编辑器删除 PDF 元数据

    如果您是第一次编辑 PDF,请先进行备份。

    使用可以处理二进制 blob 的文本编辑器打开 PDF。 vim -b 会好的。

    找到/Info 字典。用空格完全覆盖您不再需要的所有条目(条目由/Key 名称加上它们后面的(some values) 组成)。

    注意不要使用超过最初字符数的空格。否则您的xref 表(PDF 对象的目录将失效,一些查看者会指出 PDF 已损坏)。

    如需其他措施,请在 PDF 中找到 /XML 字符串。它应该向您显示 XMP/XML 元数据部分的位置(并非所有 PDF 都有它们)。在其中找到要删除的所有键值(不是<something keys>!)。同样,只需用空格覆盖它们,并注意不要更改总长度(既不长也不短)。

如果您的 PDF 无法访问 /Info 字典,请在 qpdf 的帮助下对其进行转换。

    使用这个命令:

    qpdf --qdf --object-streams=disable orig.pdf qdf---orig.pdf
    

    应用上述过程。 (qdf---orig.pdf 现在应该更适合

    重新压缩你编辑的文件:

    qpdf qdf---orig.pdf  edited---orig.pdf
    

    完成!享受您的edited---orig.pdf。检查是否已删除所有数据:

    pdfinfo -meta edited---orig.pdf
    

更新

查看提供的示例 PDF 文件后,我很清楚 /PageLabel 键不是 /Info 字典(PDF 的 文档信息字典)的一部分,而是 @ 987654339@ 对象。

这可能是pdftk 无法使用 OP 描述的方法更新它的一个原因。

其他原因如下:PDF which the OP quoted as containing the correct page labels 实际上包含不正确的!

 Logical Page No. |  Page Label
 -----------------+------------
               1  |   1
               2  |   2
               3  |   2
               4  |   2
               5  |   2
               6  |   4

另一个 PDF(supposedly contains extraneous page labels)以不同的方式不正确:

 Logical Page No. |  Page Label
 -----------------+------------
               1  |   1
               2  |   1
               3  |   2
               4  |   2
               5  |   2
               6  |   4

我关于如何手动编辑 PDF 的经典元数据的原始建议仍然有效。对于编辑页面标签的情况,您可以应用相同的方法,但略有不同。

对于 OP 的示例文件,复杂性开始发挥作用:/Root 对象无法直接访问,因为它隐藏在压缩对象流中(PDF 对象类型 /ObjStm)。这意味着必须先在qpdf 的帮助下解压它:

    使用qpdf:

    qpdf --qdf --object-streams=disable example_presentation-NOTES.pdf q-notes.pdf
    

    使用vim以二进制模式打开生成的文件:

    vim -b q-notes.pdf
    

    找到/Root 对象开头的1 0 obj 标记,其中包含一个名为/PageLabels 的字典。

    (a) 要完全禁用页面标签,只需将 /PageLabels 字符串替换为 /Pagelabels,使用小写的“l”(PDF 区分大小写,将不再识别关键字;您自己可以在其他一些如果需要,请及时恢复原始版本。)

    (b) 要编辑页面标签,首先查看第 1--6 页的连续标签是如何引用的

       <feff0031>
       [....] 
       <feff0032>
       [....] 
       <feff0032>
       [....] 
       <feff0032>
       [....] 
       <feff0033>
       [....] 
       <feff0034>
    

    (这些值以 BOM 标记的十六进制表示,表示 1、2、2、2、3、4...)

    编辑这些值以读取:

        <feff0031>
        [....] 
        <feff0032>
        [....] 
        <feff0033>
        [....] 
        <feff0034>
        [....] 
        <feff0035>
        [....] 
        <feff0036>
    

    保存文件并再次运行 qpdf 以重新压缩 PDF:

    qpdf q-notes.pdf notes.pdf
    

    现在希望这些是 OP 正在寻找的页面标签....

由于 OP 似乎熟悉编辑pdftkdump_data 输出的输出,因此他可以编辑输出并使用update_data 将修复应用于PDF,而无需求助于qpdfvim


更新 2:

用户@Iserni 发布了一个非常好的、简短且有效的答案,它将自己限制为一个命令pdftk,OP 似乎已经熟悉该命令,加上sed——不需要使用文本编辑器打开PDF,而不是像我的回答那样引入额外的实用程序qpdf

不幸的是,@Iserni 在我发表评论后再次将其删除。我认为他的回答应该得到赏金,我呼吁您投票以“取消删除”他的回答!

所以暂时,我会在此处附上@Iserni 的答案副本,直到他再次被取消删除:

不确定我是否正确理解了这个问题。您可以尝试使用屠夫的解决方案:蛮力将 /PageLabels 块替换为无法识别的其他块。

# Get a readable/writable PDF
pdftk file1.pdf output temp.pdf uncompress

# Mangle the PDF. Keep same length
sed -e 's|^/PageLabels|/BageLapels|g' < temp.pdf > mangled.pdf

# Recompress
pdftk mangled.pdf output final.pdf compress

# Remove temp file
rm -f temp.pdf mangled.pdf

【讨论】:

我的问题是生成 PDF 的软件导致页面标签不正确。有没有办法以编程方式做到这一点? @BenjaminMakoHill:嗯……那你为什么不问这个?为什么不命名“生成软件”(或至少描述一些有关其功能的更多细节)?你知道,有些 PDF 生成软件确实有影响其结果的开关,有些则没有。你让我猜…… 我更新了我的问题以提供更多上下文。非常感谢您花时间回答我的问题!我真的很感激! @Iserni:很抱歉您删除了答案!我的评论根本不是要让你这样做。老实说,我很欣赏你的简短方法,我赞成你的回答,我很高兴看到你的回答收获了赏金。请再次取消删除您的答案! (等等……我投票取消删除它。) 我确实理解并感谢您的评论(以及您的支持 :-))。但我相信 没有更彻底地检查您的答案是错误的(如果我有,我什至可能一开始都不会回答!)。请不要担心 - 没有造成伤害,没有难过的感觉,反正还会有其他场合!【参考方案2】:

不确定我是否正确理解了这个问题。您可以尝试使用屠夫的解决方案:蛮力将 /PageLabels 块替换为无法识别的其他块。

# Get a readable/writable PDF
pdftk file1.pdf output temp.pdf uncompress

# Mangle the PDF. Keep same length
sed -e 's|^/PageLabels|/BageLapels|g' < temp.pdf > mangled.pdf

# Recompress
pdftk mangled.pdf output final.pdf compress

rm -f temp.pdf mangled.pdf

【讨论】:

这是对我建议 (1) 解压缩 PDF 的回答的抄袭; (2) /PageLabels替换为/Pagelabels...; (3) 重新压缩 PDF :-) -- 诚然,虽然这个答案可能没有提供那么多的教育见解,但它更短,避免直接编辑 PDF,保留在单个pdftk 命令行实用程序的领域,整体运行速度更快。因此,它应该得到所有的支持,包括我自己的 :-) 对不起,我没有意识到 :-( -- 由于您有足够的声誉阅读已删除帖子中的 cmets,我正在节省一些时间并立即删除答案。我会如果您将我的小脚本包含在 your 答案中,将不胜感激:-)。

以上是关于如何从 PDF 中删除元数据字段(例如,PageLabel 字段)?的主要内容,如果未能解决你的问题,请参考以下文章

如何从pdf文件中删除注释

从备注字段的内容中删除特定行

从 ruby​​ 中的 pdf 文件中获取元数据

jquery:如何在提交之前从表单中删除空白字段?

从 DOI 获取元数据

如何通过文件元数据从 GridFS 中删除图像文件?