首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >characters PDF流返回偏移字符

characters PDF流返回偏移字符
EN

Stack Overflow用户
提问于 2015-08-13 23:33:44
回答 2查看 1.8K关注 0票数 0

我有使用文件文本类从PDF中提取文本的代码。直到上个星期当pdf中发生了一些变化。奇怪的是,一旦我将29个字符添加到字符的ord中,字符就会出现并更正。

示例响应调试打印:

代码语言:javascript
复制
/F1 7.31 Tf
0 0 0 rg
1 0 0 1 195.16 597.4 Tm
($PRXQW)Tj
ET
BT

代码在pdf的流部分使用gzuncompress。$PRXQW是数量,并将29 each添加到每个字符的ord中,这给了我这个结果。但有时字符将不是这个确切的翻译,如什么应该是一个)在文本中似乎是两个字节的5C66。

只是想知道这个代码环类型的字符现在从PDF出来,如果有人见过这样的事情?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-14 07:52:32

Tj操作的字符串参数的编码完全取决于所使用的PDF字体(在当前情况下为F1):

文本显示操作符的字符串操作数应解释为标识要绘制的符号的字符代码序列。 对于简单的字体,字符串的每个字节都应被视为单独的字符代码。然后在字体的编码中查找字符代码,以选择字形,如9.6.6所述,“字符编码”。 使用组合字体(PDF 1.2),可以使用多字节代码来选择象形文字.在这种情况下,字符串的一个或多个连续字节将被视为单个字符代码。代码长度和从代码到象形文字的映射是在称为CMap的数据结构中定义的,在9.7中描述了“复合字体”。 (http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/PDF32000_2008.pdf中的9.4.3节“文本-显示操作符”)

OP的代码似乎假定了标准编码,如MacRomanEncodingWinAnsiEncoding,,但这些只是特例。正如上面的引号所指出的,编码可能也是一些特殊的混合多字节编码。

后面一节中的PDF规范描述了如何正确提取文本:

符合标准的读取器可以按照给定的优先级使用这些方法将字符代码映射到Unicode值。特别是有标记的PDF文档至少应提供其中一种方法(见14.8.2.4.2,“以标记PDF表示的Unicode映射”):

  • 如果字体字典包含ToUnicode CMap (参见9.10.3,"ToUnicode CMaps"),则使用CMap将字符代码转换为Unicode。
  • 如果字体是一个简单的字体,它使用预定义的编码之一MacRomanEncodingMacExpertEncoding,或WinAnsiEncoding,,或者编码的差异数组仅包括从Adobe标准拉丁字符集和符号字体中的命名字符集合中提取的字符名(参见附件D): ( a)根据表D.1和字体的差异数组将字符代码映射到字符名。 b)在Adobe列表(请参阅书目)中查找字符名,以获得相应的Unicode值。
  • 如果字体是一种复合字体,该字体使用表118中列出的预定义CMaps之一(标识-H和标识-V除外),或者其后代CIDFont使用Adobe-GB1、Adobe-CNS1、Adobe 1或Adobe 1字符集合: ( a)根据字体的CMap将字符代码映射到字符标识符(CID)。 b)从字体的CIDSystemInfo字典中获取字体的CMap (例如,AdobeandJapan1)使用的字符集合的注册表和顺序。 ( c)通过连接注册表和格式注册表( CMap 2)中步骤(b)中获得的顺序(例如Adobe-japan1-UC 2)来构造第二个注册中心名称。 d)以步骤(c)中构造的名称获取CMap (可从ASN站点获得;请参阅书目)。 ( e)根据步骤(d)中获得的CMap映射步骤(a)中获得的CID,生成Unicode值。

如果这些方法无法生成Unicode值,则无法确定字符代码代表什么,在这种情况下,符合条件的读者可以选择他们选择的字符代码。

(http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/PDF32000_2008.pdf中的9.10.2节“将字符代码映射到Unicode值”)

因此:

只是想知道这个代码环类型的字符现在从PDF出来,如果有人见过这样的事情?

是的,在来自野外的PDF中,使用文本绘制操作符字符串参数与ASCII‘’ish完全不同的编码是相当普遍的。正如上面第二段引文中的最后一段所暗示的那样,在某些情况下根本不允许文本提取(没有OCR,也就是说),尽管还有其他地方可以查找到Unicode的映射。

票数 2
EN

Stack Overflow用户

发布于 2016-03-20 07:11:04

在最一般的情况下,您想要解码的神秘字符串是所选字体的/Encoding字段,在您的示例中是字体/F1。更有可能的是,编码方案是/Identity-H,它可以包含PDF字符串中的16位字符到UTF-16字符的任意映射。

下面是我正在编写的PDF解析器的一个示例。每个页面都包含一个资源字典,其中包含一个字体字典:

代码语言:javascript
复制
[&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|
]

在我的例子中,/F3产生了不可用的文本,所以看看/F3:

代码语言:javascript
复制
[&9|0] => Array [
    [/Type] => |/Font|
    [/Subtype] => |/Type0|
    [/BaseFont] => |/Arial|
    [/Encoding] => |/Identity-H|
    [/DescendantFonts] => |&10|0|
    [/ToUnicode] => |&96|0|
]

在这里您可以看到/Encoding类型是/Identity-H。/F3中使用的解码字符的字符解码映射存储在/ToUnicode引用的流中。以下是‘&96_

代码语言:javascript
复制
...
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
...

pairs /endbfchar之间的16位对是单个字符的映射。例如,<0003> (0x0003)映射到<0020> (0x0020),这是空格字符。

16位三重奏在起始范围/结束范围之间是字符范围的映射。例如,从<0055> (第一个)到<0059> (最后)的字符映射到<0072>、<0073>、<0074>、<0075>和<0076> ( UTF16 &ASCII中从‘r’到'v‘)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32000107

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档