【问题标题】:Ghostscript does not convert pdf file with attachmentsGhostscript 不会转换带有附件的 pdf 文件
【发布时间】:2018-09-11 09:16:40
【问题描述】:

ghostcript(9.21 版)忽略 pdf 文件中的附件

使用的命令 cmd /c %GHOST_SCRIPT_EXE% -dPDFA=2 -dBATCH -dNOPAUSE -dSubsetFonts=false -dPDFSETTINGS=/printer -sProcessColorModel=DeviceRGB -sDEVICE=pdfwrite -dCompatibilityLevel=1.7 -dOptimize=true -dPDFACompatibilityPolicy=1 -dAutoRotatePages=/None -sOutputFile ="out.pdf" "test.pdf"

如您所见,test.pdf 有一个附件 1.pdf。但在转换后的 pdf 中,即 out.pdf 没有 1.pdf。

pdf文件附在test.pdfout.pdf

【问题讨论】:

  • 您希望 Ghostscript 对附件做什么?答案是肯定的,因为 Ghostscript 是为打印而设计的,它不支持 PDF 的很多交互功能。由于附件可以是任何东西,Ghostscript 不会尝试对它们做任何事情。无论如何,除非您非常幸运,否则您的命令行不会创建有效的 PDF/A 文件,因为您没有遵循文档中的指导。
  • 感谢@KenS 的反馈。我也想将附加的 pdf 与转换后的 pdfa 一起保留。这可能吗?
  • 任何事情都是“可能的”,这是一个简单的编程问题......在我看来,这可能应该已经工作了(在当前版本的 Ghostscript,9.23 中)但是因为你还没有提供了一个例子,我无法测试它。我不确定这样做的含义,因为 (PDF/A-2) 规范谈到了“符合 PDF/A 的文件附件”,但没有说明这实际上意味着什么。该规范描述了嵌入的文件,而不是附加的文件。可能只有 PDF/A 文件作为附件是合法的。检查这将是“困难的”。
  • @KenS Ghostscript 9.23 也有同样的问题。正如您所看到的 out.png,转换后的文件没有附加 1.pdf。 (附件图标可见,但实际文件丢失)。
  • 好吧,在没有示例文件的情况下,我无话可说。 Ghostscript 中 PDF 解释器的当前实现对 FileAttachment 注释执行操作,如果生成的注释不正确,则可能是因为从它生成的 pdfmark 不正确,或者重写注释的 pdfwrite 代码有错误。 FileAttachment 注释在 ghostpdl/Resource/Init/pdf_draw.ps 中处理,因此您可以对其进行调试以查看生成的 pdfmark 并将其与原始和创建的 PDF 文件进行比较。

标签: ghostscript


【解决方案1】:

这不仅仅是一个附加文件,它是一个嵌入文件。

嵌入的数据没有被复制有几个原因。首先是因为我们在 Ghostscript 中根本不支持嵌入文件(我们不能对它们做任何有用的事情),其次是因为您正在创建 PDF/A 文件。

嵌入文件仅在 PDF/A 也是 PDF/A 文件时才有效(您的嵌入文件不是 PDF/A PDF 文件,因此需要先进行转换)。 Ghostscript 无法轻松验证这一点,因此我们(再次)不复制嵌入文件。

您可以(当然)自己增强 Ghostscript 来做到这一点。您将需要处理 /EF(嵌入式文件)键并使用 pdfmarks 创建流,然后将其插入到 FileAttachment 注释中的 /FS(FileSpec)键的字典中。

[编辑]

当前的 Ghostscript PDF 解释器是用 PostScript 编写的。如果你查看 /ghostpdl/Resource/Init/pdf_draw.ps 你会看到:

/FileAttachment {mark exch loadannot /ANN pdfmark  false} bdef

这就是处理 FileAttachment 注释的地方。可以看到,它使用了一个叫loadannot的函数,将注解字典转换成一系列的字符串存放在操作数栈上,然后加上/Ann,调用pdfmark对这些字符串进行处理。

您可以在 Adob​​e pdfmark 参考文档中找到 pdfmark 运算符(可在 Adob​​e 网站上的某个位置找到,我推荐 Google,他们一直在移动它)。

这是原始文件的样子,您需要创建 pdfmarks 来重现它:

23 0 obj
<<
  /AP <<
    /N 26 0 R
  >>
  /C [ 0.25 0.333328009 1 ]
  /Contents (1.pdf)
  /CreationDate (D:20180402114155+05'30')
  /F 28
  /FS 24 0 R                              
  /NM (55b56d89-a71e-484c-bf64-e4608540304b)
  /Name /Paperclip

  /RC (<?xml version="1.0"?><body xmlns="http://www.w3.org/1999/xhtml" xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/" xfa:APIVersion="Acrobat:11.0.21" xfa:spec="2.0.2" ><p>1.pdf</p></body>)
  /Rect [ 200.852997 727.552979 207.852997 744.552979 ]
  /Subj (File Attachment)
  /Subtype /FileAttachment
  /T (ybn9mk)
  /Type /Annot
>>
endobj

24 0 obj
<<
  /EF <<
    /F 25 0 R
  >>
  /F (1.pdf)
  /Type /Filespec
  /UF (1.pdf)
>>
endobj

25 0 obj
<<
  /DL 82637
  /Subtype /application#2Fpdf
  /Length 82637
  /Params <<
    /CheckSum <EC9AED504CB6442F260E1379E21A0873>
    /CreationDate (D:20180402114059+05'30')
    /ModDate (D:20170907123559+05'30')
    /Size 82637
  >>
>>
stream
%PDF-1.5
.....
.... embedded PDF file here
....
....
endstream
endobj

当前的 Ghostscript 实现将重现对象 23,即 FileAttachement 注释,并将正确地将 /EF 字典内联扩展到该注释中。但是,它不会写入对象 25,即实际嵌入的 PDF 文件。

因此您需要添加代码来读取嵌入式文件对象,使用 pdfmark 将其写入命名内容流,然后从 FileSpec 字典中的 /EF 键引用该命名对象流(原始文件中的对象 24文件,但扩展并包含在 pdfwrite 输出中)。

除非您非常熟悉 PostScript,否则这将是一个相当大的挑战。

【讨论】:

  • 感谢@KenS 的回答。如果您详细说明增强 ghost 脚本以将嵌入的 pdfa 包含在输出 pdfa 文件中,那就太好了。我是幽灵脚本的新手,无法理解您的最后一段。
猜你喜欢
  • 2022-01-19
  • 2014-11-20
  • 2013-09-25
  • 2017-09-14
  • 2017-02-21
  • 1970-01-01
  • 2017-08-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多