【问题标题】:How to reference text content in preformatted PDF (QDF)?如何引用预格式化 PDF (QDF) 中的文本内容?
【发布时间】:2021-04-25 18:03:05
【问题描述】:

使用文本编辑器编辑 PDF 文件的源代码时,我可以通过多次引用一个对象来多次使用它。

这个例子是对对象 15 的引用:

  /Resources <<
    /XObject <<
      /Fm0 15 0 R
    >>
  >>

如果对象 15 是文本,则该文本将出现在 PDF 查看器中它被引用的每个位置。但它将始终采用 /Resources 下和对象 15 内的 stream 中定义的字体和大小:

15 0 obj
<<
  /BBox [
    3.24609
    767.215
    507.739
    819.297
  ]
  /FormType 1
  /Resources <<
    /Font <<
      /F1 25 0 R
    >>
    /ProcSet [
      /PDF
      /Text
      /ImageB
      /ImageC
      /ImageI
    ]
  >>
  /Subtype /Form
  /Type /XObject
  /Length 16 0 R
>>
stream
q
0 g
BT
0 Tr
/F1 25 Tf
1 0 0 1 36 785.248 Tm
[(0123)] TJ
ET
Q
endstream
endobj

我真正需要的是有一串字符(实际上是四位数字),它在 PDF 源代码的两个或多个位置被引用。但是,每次使用的字体和大小都不同,而两种字体的编码相同(即,转换为 QDF 格式后,使用的字符在文本编辑器中可以作为纯文本读取 - 只要它们在 ASCII 范围内范围)。

所以我想我要找的是两件事:

  1. 将文本字符串添加到 PDF 文件的正确方法,以便我可以
  2. 从不同的流中引用它。

––> 有没有办法做到这一点?

[要求一旦准备好,如果我在要修改的行上方添加注释,则可以在任何系统上将四个数字替换为四个不同的数字,以便他们可以轻松找到正确的位置。无需先安装软件或字体(已嵌入在预格式化的 PDF 中),只需使用文本编辑器即可。]

【问题讨论】:

    标签: pdf qpdf


    【解决方案1】:

    在文本编辑器中编辑文本不是 PDF 的设计用例。因此,如果您不期望有通用解决方案满足您的要求,请不要太惊讶。

    在某些特殊情况下,您可以实施解决方案。尽管如此,作为一个整体的要求是个坏主意。

    一个糟糕的要求

    要求是,一旦准备好,如果我在要修改的行上方添加注释,则可以在任何系统上将四个数字替换为四个不同的数字,以便他们可以轻松找到正确的位置。无需先安装软件或字体(已嵌入在预格式化的 PDF 中),只需使用文本编辑器即可。

    这是一个不好的要求。使用十六进制编辑器编辑 PDF 已经很微妙了,但至少可以确保您不会无意中更改您不想更改的内容。许多文本编辑器在这方面有所不同并应用更改(在实际文本文档的情况下并不重要,但在 PDF 的情况下)。

    再次使用 QPDF 对编辑后的 ​​PDF 进行后处理可以将这种影响相对化,但这种方法会发生错误。

    表单 XObjects

    Form XObjects 并不是您问题的真正解决方案,因为它们不代表孤立的字符串,而是完整的、完全样式化的内容 片段。它们可以转换为调整大小或旋转,每次使用都不同,但不能重新设置样式。

    (好吧,您可以尝试使用过时的选项来使用没有 Resources 条目的 Form XObject;该对象将继承它所显示的页面的资源。不同的页面可能在它们的资源具有与 XObject 中使用的字体名称相关联的不同字体。这样,您至少可以在不同页面上以不同样式使用该数字。但如上所述,此构造已过时,因此不应使用。 )

    页面内容流

    如果显示有关四位数字的说明的文本只需要出现在页面级别(即不在某些 XObject、Pattern 等中),您可以利用页面 Contents 可以排列为一系列流。

    例如:

    %PDF-1.7
    %äöü
    1 0 obj
    <<
    /Length 9
    >>
    stream
    (1234) Tj
    endstream
    endobj 
    [... more indirect objects ...]
    100 0 obj
    /Type/Page 
    /Contents [101 0 R 1 0 R 102 0 R 1 0 R 103 0 R]
    [... more page entries ... ]
    endobj
    101 0 obj
    <<
    /Length XXX
    >>
    stream
    [... some page specific drawing instructions ...]
    BT
    1 0 0 1 30 600 Tm
    /Font1 10 Tf
    endstream
    endobj 
    102 0 obj
    <<
    /Length XXX
    >>
    stream
    ET
    [... some page specific drawing instructions ...]
    BT
    0 1 -1 0 300 300 Tm
    /Font2 20 Tf
    endstream
    endobj 
    103 0 obj
    <<
    /Length XXX
    >>
    stream
    ET
    [... some page specific drawing instructions ...]
    endstream
    endobj 
    [... more indirect objects and the whole end-of-file stuff ...]
    

    这里页面对象 100 的内容分布在多个流中:

    • 101 以一些特定页面的绘图指令开头;然后它启动一个文本对象,转到 (30, 600),并选择大小为 10 的 Font1;
    • 1 绘制字符串;
    • 102 结束文本对象并执行更多特定于页面的绘图指令;然后它开始另一个文本对象,在 90° 处转到 (300, 300),并选择大小为 20 的 Font2;
    • 1 绘制字符串;
    • 103 结束文本对象并执行更多特定于页面的绘图指令。

    AcroForm 文本字段

    另一种选择是使用 AcroForm 文本字段。

    此类文本字段具有单个值但具有多个可视化(小部件注释),并且不同的可视化可能具有不同的 DA 默认外观值,PDF 查看者可以根据这些默认外观值构建外观。

    但这并不适用于所有 PDF 查看器。

    此外,在 PDF-2.0 中,您应该为所有小部件提供实际外观流。

    【讨论】:

    • 哇,您的示例看起来与我所追求的完全一样。 PDF 将只包含一页,所以应该没问题。接下来的几天我没有太多时间,但是一旦我完成了这个工作,我就会回到这里。到目前为止,非常感谢!
    • 根据您的回答,我最终设法按照我想要的方式修改了 PDF。值得一提的是,只有当我将间接对象放在页面内容定义之后,PDF 才会起作用。 • 我的文本编辑器不会自行应用任何更改。但是我理解你说我的要求不好。因此,任何以这种方式编辑 PDF 的人都必须知道他们在做什么。 • 通过这个工作,我学到了很多东西。但如果没有你的彻底回答,我是不会成功的。再次感谢!
    • 纠正我上一条评论:我认为间接对象可以在 PDF 的顶部,所以在页面对象之前,只要它们的对象编号高于页面对象的编号。只需修改对象开始位置的外部参照中的相应字节数。
    • 很高兴它为您工作。但是文件中的对象数量或位置应该没有限制。只要从交叉引用表/流中正确引用对象,任何对象都可以在任何地方。
    • 如果我将“1 0 obj”分配给“待编辑”间接对象,macOS 中的“预览”将不会显示 PDF。它仅适用于高于页面对象的对象编号。但我不能完全排除其他原因。 • 在我的测试中,PDF 在 Preview、Acrobat、QuarkXPress、InDesign、Illustrator、FreeHand 和 Photoshop 中运行良好。
    猜你喜欢
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多