返回偏移字符的PHP筛选器FlateCode PDF流
我有使用filetotext类从PDF中提取文本的代码。一直工作到上周,pdf中的某些内容发生了变化。奇怪的是,当我在角色的ord中添加29个字符时,这些字符似乎在那里并且是正确的 示例响应调试打印输出:返回偏移字符的PHP筛选器FlateCode PDF流,php,pdf,character-encoding,text-extraction,Php,Pdf,Character Encoding,Text Extraction,我有使用filetotext类从PDF中提取文本的代码。一直工作到上周,pdf中的某些内容发生了变化。奇怪的是,当我在角色的ord中添加29个字符时,这些字符似乎在那里并且是正确的 示例响应调试打印输出: /F1 7.31 Tf 0 0 0 rg 1 0 0 1 195.16 597.4 Tm ($PRXQW)Tj ET BT 该代码在pdf的流部分使用gzuncompress。 $PRXQW是Amount,在每个字符的ord中加上29dec就得到了这个值。但有时一个字符并不是这样精确翻译的,
/F1 7.31 Tf
0 0 0 rg
1 0 0 1 195.16 597.4 Tm
($PRXQW)Tj
ET
BT
该代码在pdf的流部分使用gzuncompress。
$PRXQW是Amount,在每个字符的ord中加上29dec就得到了这个值。但有时一个字符并不是这样精确翻译的,比如文本中应该是a)的字符看起来是两个字节的5C66
想知道现在PDF中出现的这种码环字符类型,是否有人见过这种情况?Tj操作的字符串参数的编码完全取决于所使用的PDF字体(F1): 显示运算符的文本的字符串操作数应解释为识别待绘制符号的字符代码序列 对于简单字体,字符串的每个字节应视为单独的字符代码。然后,应在字体编码中查找字符代码,以选择字形,如9.6.6“字符编码”中所述 对于复合字体(PDF 1.2),多字节代码可用于选择字形。在这种情况下,字符串的一个或多个连续字节应视为单字符代码。代码长度和从代码到字形的映射在称为CMap的数据结构中定义,如9.7“复合字体”中所述 (中第9.4.3节“显示操作员的文本”) OP的代码似乎采用了标准编码,如宏编码或winansioncoding,但这些只是特例。正如上面的引文中所指出的,编码也可能是一些特殊的混合多字节编码 后面一节中的PDF规范介绍了如何正确提取文本: 一致性读取器可以按照给定的优先级使用这些方法将字符代码映射到Unicode值。尤其是带标签的PDF文件,应至少提供其中一种方法(见14.8.2.4.2,“带标签PDF中的Unicode映射”):
- 如果字体字典包含ToUnicodeCMap(请参阅9.10.3“ToUnicode CMap”),请使用该CMap将字符代码转换为Unicode
- 如果字体是使用预定义编码之一的简单字体,MacRomanEncoding、MacExpertEncoding或WinAnScienceODing,或者其编码的差异数组仅包括取自Adobe标准拉丁字符集的字符名和符号字体中的命名字符集(见附录D): a) 根据表D.1和字体的差异数组,将字符代码映射到字符名称 b) 在Adobe Glyph列表(参见参考书目)中查找字符名以获得相应的Unicode值
- 如果字体是使用表118中列出的预定义CMAP之一的复合字体(Identity–H和Identity–V除外),或者其子代CIDFont使用Adobe-GB1、Adobe-CNS1、Adobe-Japan1或Adobe-Korea1字符集: a) 根据字体的CMap将字符代码映射到字符标识符(CID) b) 从其CIDSystemInfo字典中获取字体的CMap(例如Adobe和Japan1)使用的字符集合的注册表和顺序 c) 通过将注册表和步骤(b)中获得的排序以注册表–排序–UCS2(例如Adobe–Japan1–UCS2)的格式连接起来,构造第二个CMap名称 d) 使用步骤(c)中构造的名称获取CMap(可从ASN网站获得;请参阅参考书目) e) 根据步骤(d)中获得的CMap映射步骤(a)中获得的CID,生成Unicode值
是的,在野生PDF中,文本绘制运算符字符串参数的编码方式与ASCII格式完全不同是很常见的。正如上面第二段引文的最后一段所暗示的那样,有些情况根本不允许文本提取(即没有OCR),即使有其他地方可以查找到Unicode的映射。Tj操作的字符串参数的编码完全取决于所使用的PDF字体(F1在本案中): 显示运算符的文本的字符串操作数应解释为识别待绘制符号的字符代码序列 对于简单字体,字符串的每个字节应被视为单独的字符代码。然后,应在字体编码中查找字符代码,以选择字形,如9.6.6“字符编码”中所述 对于复合字体(PDF 1.2),可使用多字节代码选择字形。在这种情况下,字符串的一个或多个连续字节应视为单字符代码。代码长度和从代码到字形的映射在称为CMap的数据结构中定义,如9.7“复合字体”中所述 (中第9.4.3节“显示操作员的文本”) OP的代码似乎采用了标准编码,如MacRomanEncoding
[&3|0] => Array [
[/Type] => |/Page|
[/Resources] => Array [
[/Font] => Array [
[/F1] => |&5|0|
[/F2] => |&7|0|
[/F3] => |&9|0|
[/F4] => |&14|0|
[/F5] => |&16|0|
]
]
[/Contents] => |&4|0|
]
[&9|0] => Array [
[/Type] => |/Font|
[/Subtype] => |/Type0|
[/BaseFont] => |/Arial|
[/Encoding] => |/Identity-H|
[/DescendantFonts] => |&10|0|
[/ToUnicode] => |&96|0|
]
...
beginbfchar
<0003> <0020>
<000F> <002C>
<0015> <0032>
<001B> <0038>
<002C> <0049>
<003A> <0057>
endbfchar
...
beginbfrange
<0044> <0045> <0061>
<0047> <004C> <0064>
<004F> <0053> <006C>
<0055> <0059> <0072>
endbfrange
...
beginbfchar
<005C> <0079>
<00B1> <2013>
<00B6> <2019>
endbfchar
...