PDF文本字符串的编码

您所在的位置:网站首页 pdf中文是什么 PDF文本字符串的编码

PDF文本字符串的编码

2024-07-12 16:59| 来源: 网络整理| 查看: 265

我正在研究用于PDF(文本提取)的解析器。

当需要对页面进行平面解码(通过zlib压缩)时,我的代码能够解压缩内容流,然后输出(流对象),如下所示:

12345BT 56.8 721.3 Td /F2 12 Tf [22-102-221]TJ ET

我对字符串数组(TJ的操作数)感兴趣。

此数组中似乎包含多个十六进制编码的字符串,但是相应的十六进制值没有意义。而是出现了像010203这样的序列...有点lz77压缩。

PDF是否具有多个压缩级别? 如何从字符串数组上方获取纯文本?

在开始这样一个雄心勃勃的项目之前,您应该使自己熟悉完整的官方PDF-1.7规范。请注意:这是756页的文档,它引用了约90个其他文档,对于PDF来说,它也被称为"规范"。

您将学到,为了将PDF源代码反向转换为文本内容,必须反向应用字体使用的编码。可以使用5种规范定义的标准编码:

StandardEncoding MacRomanEncoding WinAnsiEncoding PDFDocEncoding MacExpertEncoding

最重要的是,还可以有一个CustomEncoding(当嵌入字体是子集时不起作用,它不包含字体定义的所有字形,而仅包含文档所需的那些字形)。如果PDF内定义了/ToUnicode表,则只能反转CustomEncode-d文本。只有这样,您才可以将编码的字符反向映射到字符名称。

您还将学到,不仅有一个,而且有四个可用于显示文本字符串的运算符:

Tj:"显示文字" Tj:"显示文本,允许单个字形定位" ':"移至下一行并显示文本" ":"设置单词和字符的间距,移至下一行,并显示文本"

此外,有三种不同的方式来表示文本字符串。这里以字符串" string"为例:

(string):这在括号内使用标准的可打印ASCII字符(仅对于拉丁/ ASCII文本部分可用)。 (\\163\\164\\162\\151\\156\\147):这使用八进制字符代码(也在括号内),如规范文档的"附录D(规范性字符集和编码)"中所列。 :这在尖括号内使用十六进制编码的字符代码。

文本提取器的问题如下:

使用可打印的ASCII字符(上面的1.)和八进制字符代码(上面的2.)可以混合使用。以下所有内容也是字符串" string"的"合法"表示形式(列表不完整!):

1234 (\\163tring)Tj  (\\163\\164\\162\\151\\156g) Tj  (st\\162i\\156g)  Tj  ...

使用十六进制编码的字符代码(上面的3.)也不是一件容易的事,因为以下所有表示形式都是等效的:

123456789101112 TJ TJ TJ TJ TJ

有关PDF规范允许的更多怪异(或Adobe观看者可以容忍的怪异),另请参见例如:

PDF技巧(@corkami的Ange Albertini撰写)

我本人最近创建了一系列手工编码的PDF文件,这些文件演示了丢失,不正确,已操纵或正确的/ToUnicode表如何影响任何PDF到文本反转的结果: 为什么文本提取不适用于所有PDF (该资料库以手工编码的PDF形式包含更多研究材料,突出显示了PDF语法的其他部分和运算符。)

最后,查看OP提供的一小段PDF源代码:

12345BT 56.8 721.3 Td /F2 12 Tf [22-102-221]TJ ET

BT和ET表示显示段

的文本的开头和结尾

56.8 721.3 Td将当前点定位到坐标"水平为56.8点,垂直为721.3点"。

12 Tf将字体大小设置为12点。

/F1将要使用的字体设置为PDF文档中其他位置定义的字体。该字体还在某处设置了字体编码(可能还有一个/ToUnicode表)。当在文本字符串中看到特定的字符代码时,字体编码将确定应绘制哪种字形形状。

[22-102-221]TJ

最后一部分可以分为以下几个部分:

2:是第一??个字符代码。 2是使用文本显示运算符Tj时允许的"单个字形定位"的参数。 2:是另外两个字符代码。 2还是Tj的"单个字形定位"的参数。 -10:是第四个字符代码。再次使用-10和Tj进行"单个字形定位"。 2:是第五个字符代码,是第三个字符代码(以前使用)。 2用于"单个字形定位" ... 等等。

单个字形定位:单个字形定位的工作方式如下:

正数将下一个字形向左移动(减小到下一个字形的字形间隔)。 负数会将下一个字形向右移动(向下一个字形添加更多空间)。 数字本身应视为代表当前单位的千分之一。

字符代码的含义:要知道第一个,第二个,第三个,...最后一个字符代码的含义,您必须在PDF的/ToUnicode表中查找这些字符。如果它没有嵌入这样的表,那么运气不好!

检查文本的易提取性:要检查您的PDF是否很容易进行文本提取,可以使用命令行工具pdffonts。这是示例输出:

12345$ 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

在上述示例情况下,子集字体SSKFGJ+ArialMT使用自定义编码,但PDF对此字体没有/ToUnicode,如标题为uni的列所示。因此,要提取使用该字体显示的文本并不容易(提取需要手动进行反向工程-但您也可以仅"阅读" PDF页面)。

相关讨论 我有一个/ ToUnicode表,我得到的内容是这样的尖括号文本-如何解码文本? 部分是十六进制编码的文本字符串。您可以手动解码(通过引用ASCII表),也可以运行Ghostscript命令行,如下所示:IFS=""; gs -dNODISPLAY -q -c"" == quit进行解码... 您能帮我解码一下吗: @KaranAhuja:十六进制解码为ASCII字符串(&/*\\022*2'5\\(-\\003+,1-$:$',\\003\\(6&52:)。现在需要/ToUnicode表将其转换为(可能是)可读文本... 解码十六进制编码的文本字符串的一种更简便的方法是使用xxd -r -p而不是Ghostscript。例如:echo '0026002f002a0012002a0032002700350028002d0003002b002c0031002??d0024003a00240027002??c0003002800360026003??50032003a' | xxd -r -p @ hackerb9:当您学习更多其他答案时,您可能会发现,我也喜欢将Ghostscript用作针对更常见问题和任务的"非常规"解决方案...。 在@KaranAhuja示例中,我了解了如何在Unicode表中查找大多数十六进制解码的字符串,包括八进制" \\\\ 022"和" \\\\ 003"。我不明白的是如何解码最后一部分:" \\\\(6

Abhishek,

这不是一个简单的问题,不幸的是,它表明您尚未阅读PDF规范。您应该这样做。

您可以在此处下载Acrobat SDK: http://www.adobe.com/devnet/acrobat/sdk/eula.html

其中一部分是PDF规范,这是一个非常繁重的文档,解释了PDF的来龙去脉(包括对问题的回答)。

简而言之-而不是代替阅读文档-您正在寻找的是/ F2 12 Tf命令设置的字体编码中的字符值,该命令设置随后写入文本时使用的特定字体。

相关讨论 啊,我在偷看PDF规范的相关部分,但我从来没有想到它可以用字体定义:)感谢您为我指出了正确的方向,我将阅读更多内容。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3