我正在研究PDF(文本提取)的解析器.
当页面需要Flate Decoded(来自zlib压缩)时,我的代码能够解压缩内容流,然后我有输出(流对象),如下所示:
BT
56.8 721.3 Td
/F2 12 Tf
[<01>2<0203>2<04>-10<0503>2<04>-2<0506070809>2<0A>1<0B>]TJ
ET
Run Code Online (Sandbox Code Playgroud)
我对字符串数组(TJ的操作数)感兴趣.
看起来这个数组中包含多个十六进制编码的字符串,但相应的十六进制值没有意义.相反,它出现了像010203这样的序列......类似于lz77压缩.
Kur*_*fle 51
在开始这样一个雄心勃勃的项目之前,您应该熟悉完整的 官方PDF-1.7规范.请注意:这是一份756页的文档,它引用了大约90个其他文档,它们声称它们也是PDF的"规范"文档.
您将了解到,为了将PDF源代码反转为文本内容,您必须反向应用字体使用的编码.可以使用5种规范定义的标准编码:
StandardEncodingMacRomanEncodingWinAnsiEncodingPDFDocEncodingMacExpertEncoding最重要的是,还可以有一个CustomEncoding(当嵌入字体是子集时,它会发挥作用,并且不包含字体定义的所有字形,但只包含文档所需的字形).如果/ToUnicode在PDF中定义了表,则只能反转CustomEncode-d文本.只有这样,您才能将编码的字符反向映射到字符名称.
您还将了解到,不仅有一个,而且有四个运算符可用于显示文本字符串:
Tj:"显示文字"TJ:"显示文本,允许单独的字形定位"':"移至下一行并显示文字"":"设置单词和字符间距,移动到下一行,并显示文本"此外,有三种不同的方式来表示文本字符串.这里给出了字符串"string"的示例:
(string):这在括号内使用标准的可打印 ASCII字符(仅适用于拉丁文/ ASCII文本部分).(\163\164\162\151\156\147):这使用八进制字符代码(也在括号内),如规范文档的"附录D(规范)字符集和编码"中所列.<737472696E67>:这在尖括号内使用十六进制编码的字符代码.文本提取器的问题如下:
可以混合使用可打印的ASCII字符(1.上面)和八进制字符代码(2.上面).以下所有内容也是字符串"string"的 "合法"表示(列出不完整!):
(\163tring)Tj
(\163\164\162\151\156g) Tj
(st\162i\156g) Tj
...
Run Code Online (Sandbox Code Playgroud)使用十六进制编码的字符代码(3.上面)也不是直截了当的,因为以下所有表示都是等效的:
<73 74 72 69 6E 67> TJ
<73 7472 696E67> TJ
<7 374 7 269 6E 67>TJ
<73 74 72696E 67> TJ
<73
74 7
2 69 6E 67>
TJ
Run Code Online (Sandbox Code Playgroud)对于PDF规范允许的更多怪异(或Adobe观众容忍),请参阅例如:
我自己最近创建了一系列手工编写的PDF文件,演示了丢失,不正确,操作或正确的/ToUnicode表如何影响任何PDF-to-Text反转的结果:
最后,看一下OP提供的一小段PDF源代码:
BT
56.8 721.3 Td
/F2 12 Tf
[<01>2<0203>2<04>-10<0503>2<04>-2<0506070809>2<0A>1<0B>]TJ
ET
Run Code Online (Sandbox Code Playgroud)
BT并ET指出显示部分的文本的开头和结尾
56.8 721.3 Td将当前点定位到坐标"水平56.8点,垂直方向721.3点".
12 Tf 将字体大小设置为12磅.
/F1将要使用的字体设置为PDF文档中其他位置定义的字体.该字体也在某处设置字体编码(可能还有/ToUnicode表格).当在文本字符串中看到特定字符代码时,字体编码将确定应绘制哪个字形.
[<01>2<0203>2<04>-10<0503>2<04>-2<0506070809>2<0A>1<0B>]TJ
最后一部分可以分解为这些部分:
<01>2:<01>是第一个字符代码.2是使用文本show运算符时允许的"单个字形定位"的参数TJ.<0203>2:<0203>还有两个字符代码.2再次是对参数"个人字形定位"的TJ.<04>-10: <04>是第四个字符代码.-10再次为"个体雕文定位"搭配TJ.<0503>2: <05>是第五个字符代码,<03>是第三个字符代码(之前使用过).2用于"个体字形定位" ......单个字形定位:单个字形定位的工作方式如下:
字符代码的含义:要知道第一个,第二个,第三个,......最后一个字符代码的含义,您必须在/ToUnicodePDF表格中查找这些代码.如果它没有嵌入这样的表,那么运气不好!
检查文本的易提取性:要检查PDF是否适合文本提取,可以使用命令行工具pdffonts.这是一个示例输出:
$ pdffonts sample.pdf
name type encoding emb sub uni object ID
------------------------- ------------- ------------ --- --- --- ---------
IADKRB+Arial-BoldMT CID TrueType Identity-H yes yes yes 10 0
SSKFGJ+ArialMT CID TrueType Custom yes yes no 11 0
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,子集化字体SSKFGJ+ArialMT使用自定义编码,但PDF没有/ToUnicode此字体,如标题列所示uni.因此,提取用这种字体显示的文本并不容易(提取需要手动逆向工程 - 但是你也可以"阅读"PDF页面).
阿比舍克
这不是一个简单的问题,不幸的是,它表明您尚未阅读PDF规范。您应该这样做。
您可以在此处下载Acrobat SDK:http: //www.adobe.com/devnet/acrobat/sdk/eula.html
其中一部分是PDF规范,这是一个非常繁重的文档,解释了PDF的来龙去脉(包括对问题的回答)。
简而言之,而不是代替阅读文档,您正在寻找的是/ F2 12 Tf命令设置的字体编码中的字符值,该命令设置了随后编写文本时使用的特定字体。