首页 文章

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

提问于
浏览
0

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

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

test.pdf

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

pdf文件附有test.pdfout.pdf

1 回答

  • 0

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

    由于多种原因,不会复制嵌入数据 . 首先是因为我们根本不支持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来处理字符串 .

    您可以在Adobe pdfmark参考中找到pdfmark运算符(可在Adobe网站上的某处获得,我推荐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,否则这将是一个非常大的挑战 .

相关问题