代码之家  ›  专栏  ›  技术社区  ›  JavaGeek

Ghostscript不转换带有附件的pdf文件

  •  1
  • JavaGeek  · 技术社区  · 6 年前

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

    使用的命令 cmd/c%GHOST\u SCRIPT\u EXE%dPDFA=2-dBATCH-dNOPAUSE-dsubsetfont=false-dPDFSETTINGS=/printer-sProcessColorModel=DeviceRGB-sDEVICE=pdfwrite-dCompatibilityLevel=1.7-dOptimize=true-dPDFACompatibilityPolicy=1-dAutoRotatePages=/None-sOutputFile=“out.pdf”test.pdf

    test.pdf

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

    pdf文件随附 test.pdf out.pdf

    1 回复  |  直到 6 年前
        1
  •  0
  •   KenS    6 年前

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

    由于以下几个原因,未复制嵌入的数据。首先,因为我们根本不支持Ghostscript中的嵌入文件(我们无法对它们做任何有用的事情),其次,因为您正在创建PDF/a文件。

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

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

    [编辑]

    当前的Ghostscript PDF解释器是用PostScript编写的。如果您查看/ghostpdl/Resource/Init/pdf\u draw。ps您将看到:

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

    这就是处理FileAttachment注释的地方。如您所见,它使用一个名为loadannot的函数将注释字典转换为存储在操作数堆栈上的一系列字符串,然后添加/Ann并调用pdfmark来处理这些字符串。

    您可以在Adobe pdfmark参考中找到pdfmark操作符(可在Adobe网站上找到,我推荐谷歌,他们会不断移动它)。

    以下是原始文件的外观,您需要创建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,否则这将是一个相当大的挑战。