首先是一般性问题
如果编码和ToUnicode都存在于pdf中,如何提取pdf中的文本?如何映射它?
[...] 如果您看到编码和 ToUnicode 都存在于 pdf 中。我知道是否只有 ToUnicode 存在,所以如何使用 Cmap 文件映射单个字符。
在这种情况下,即当您同时拥有足够完整和正确的ToUnicode映射和字体的编码时,您可以忽略编码并仅使用ToUnicode映射。
这遵循 PDF 规范,该规范在第 9.10.2 节“将字符代码映射到 Unicode 值”中指出,将字符代码映射到具有最高优先级的 Unicode 值的方法是
如果字体字典包含 ToUnicode CMap(参见 9.10.3,“ToUnicode CMaps”),则使用该 CMap 将字符代码转换为 Unicode。
因此,如果您(如您所说)已经知道在只有ToUnicode映射的情况下如何提取文本,则可以使用相同的算法不变。作为推论,如果这不起作用,则有问题的ToUnicode映射不够完整或不正确,或者您对如何仅使用ToUnicode映射提取文本的知识本身实际上是不完整的。
其次是样本文件
你写了
[()-2.11826()-1.14177()2.67786()-2.11826()8.55269()-5.44998()-4.70186()2.67786()-2.32338()2.67786()12.679()-3.75591()9.73429() TJ
在 break-at 中有一些不可见的垃圾数据。那么如何将数据链接到cmap文件?
括号中是标识字形的值,因此它们绝对不是垃圾。
因此,这里是括号内的字节值:
[(
01
)-2.11826(
02
)-1.14177(
03
)2.67786(
01
)-2.11826(
04
)8.55269(
05
)-5.44998(
06
)-4.70186(
07
)2.67786(
04
)-2.32338(
07
)2.67786(
08
)12.679(
09
)-3.75591(
02
)9.73429(
04
)]TJ
使用相关字体的ToUnicode映射
/CIDInit /ProcSet findresource begin
12 dict begin
begincmap
/CMapType 2 def
1 begincodespacerange
<00><ff>
endcodespacerange
9 beginbfrange
<01><01><0054>
<02><02><0045>
<03><03><0053>
<04><04><0020>
<05><05><0050>
<06><06><0044>
<07><07><0046>
<08><08><0049>
<09><09><004c>
endbfrange
endcmap
CMapName currentdict /CMap defineresource pop
end end
括号内的字节值映射到:
01 0054 "T"
02 0045 "E"
03 0053 "S"
01 0054 "T"
04 0020 " "
05 0050 "P"
06 0044 "D"
07 0046 "F"
04 0020 " "
07 0046 "F"
08 0049 "I"
09 004c "L"
02 0045 "E"
04 0020 " "
因此,
"TEST PDF FILE "
与渲染文件匹配得很好:
三、编码
另一个问题是 /Encoding 中包含的值是什么?
10 0 obj << /BaseEncoding /WinAnsiEncoding /Differences [ 1 /g100 /g28 /g94 /g3 /g87 /g24 /g38 /g47 /g62 ] /Type /Encoding >>
根据 PDF 规范,
差异条目的值应是一组字符代码和字符名称,其组织方式如下:
代码1 名称1,1 名称1,2 ...</p>
代码2 名称2,1 名称2,2 ...</p>
…</p>
代号n 名称n,1 名称n,2 ...</p>
每个代码应是要更改的字符代码序列中的第一个索引。代码后的第一个字符名称成为该代码对应的名称。随后的名称替换连续的代码索引,直到下一个代码出现在数组中或数组结束。这些序列可以按任何顺序指定,但不得重叠。
因此,在您的情况下,编码条目表示编码基本上是WinAnsiEncoding,不同之处在于代码 1、...、9 代表名为 /g100、/g28、/g94、/g3、/g87、/g24 的字形、/g38、/g47 和 /g62。
由于这些字形名称不是标准字形名称,因此 PDF 规范不认为这种编码对文本提取有帮助,因为它只描述了一种简单字体的方法
有一个编码,其差异数组仅包含取自 Adobe 标准拉丁字符集的字符名称和符号字体中的命名字符集(参见附录 D)
您的示例中的“/gXX”名称显然不在其中。