Ghostscript 不会生成带有在 DOCINFO 中检测到的 UTF16BE 文本字符串的 PDF/A - 尽管 PDFACompatibilityPolicy 另有说明

Hag*_*zen 3 pdf pdf-generation ghostscript

我正在尝试使用以下命令行将普通 PDF 文件转换为 PDF/A:

gs -dPDFA -dBATCH -dNOPAUSE -sProcessColorModel=DeviceCMYK -sDEVICE=pdfwrite -sPDFACompatibilityPolicy=1 -sOutputFile=output.pdf input.pdf
Run Code Online (Sandbox Code Playgroud)

但是,我收到消息

GPL Ghostscript 9.26: UTF16BE text string detected in DOCINFO cannot be represented in XMP for PDF/A1, reverting to normal PDF output
Run Code Online (Sandbox Code Playgroud)

gs 恢复为普通 PDF。显然,该消息源于gs 的这个代码片段,但我们在那里读到该消息仅在pdev->PDFACompatibilityPolicy == 0. 我的理解是-sPDFACompatibilityPolicy=1命令行中的参数旨在防止这种情况。

问:为什么 gs 表现得好像所需的策略是 0 而不是 1?还有另一种方法可以将策略设置为 1 吗?

此外,正如它让我感到好奇:

问:有没有办法查看导致原始问题的奇怪 DOCINFO 类型或首先预防它?使用 Acrobat Reader,我看不到文件中的任何“可疑”内容。如果有帮助: input.pdf 是在 Word 的 Window 上生成的(我什至尝试使用 UseISO19005-1 设置,该设置应该生成 PDF/A,但无论如何都会出现问题)。

Ken*_*enS 5

你已经把-sPDFACompatibilityPolicy=1. 那恐怕是不正确的。Ghostscript 有两种开关-s处理字符串值,以及-d处理数字和名称值(PostScript 中的名称以“/”开头)。

您已将字符串值“1”分配给参数 PDFACompatbilityPolicy,该参数(内部)需要一个数值。由于需要从 PostScript 环境访问这些值这一事实,我们不能将类型混淆标记为错误。相反,我们将实际控件保留为其默认值 0。

如果你改为设置-dPDFACompatibilityPolicy=1I expect 你会看到你期望的行为。

至于看数据,不看PDF文件我无法判断。但是,如果您此时停止调试器并查看 p->data,您将能够看到数据是什么。如果您查看pairs + i而不是pairs + i + 1您将能够看到与来自 DOCINFO pdfmark 的值相关联的键。

通过在 Acrobat 中查看文件,您将看不到任何“可疑”内容,因为 Acrobat 会将 UTF16BE 转换为您的系统需要的任何内容,以便正确显示文本。甚至可能这是 ASCII,您仍然可以将其表示为 UTF16。

如果您在文本编辑器中打开文件,您可能会看到相关的字符串(请注意,Ghostscript 中的 BOM 是八进制的,因此十六进制是 0xFE 0xFF),前提是它不在压缩对象流中。


exa*_*exa 5

检查最新的 Ghostscript (9.50) 的源代码,似乎PDFACompatibilityPolicy这种情况下的值(参见devices/vector/gdevpdfm.c第 1951 行左右)将包含错误的行为设置为如下:

  • 0 将恢复为正常的 PDF 输出(不是我真正想要的)
  • 1将丢弃PDFINFO(更糟糕)
  • 2 会抛出错误(甚至更糟)
  • 任何其他值在开关中都会被忽略并作为传递!

所以,就我而言,整个问题只需设置即可解决

-dPDFACompatibilityPolicy=3
Run Code Online (Sandbox Code Playgroud)

Ghostscript 不会抱怨,不会中止 PDF/A 输出,不会丢弃 PDFINFO,最重要的是,veraPDF 检查器仍然验证 PDF 是否完全正常。

我并不是在评论这个解决方案有多丑陋,但它的效果非常好。由于所有其他 switch 语句仅假设0传入 2 以上的任何内容时的兼容性策略,因此此“快捷方式”似乎是一个无意的但非常有用的错误。