1

我正在使用一个小的 PHP 类(pdf2text)来打开和阅读“文本”PDF。

目前我无法让它正确处理 è、ä、ö、ü 等特殊字符。我尝试将标头设置为 UTF-8 并将接收数据编码为 UTF-8,但它们仍然无法正确显示。

该课程可以在这里找到:http: //pastebin.com/PSmu03nH

如果有人有任何进一步的想法甚至解决方案,请告诉我。

4

1 回答 1

3

简而言之:

您使用的PDF2Text类忽略了 PDF 规范ISO-32000-1:2008的很大一部分。它仅适用于非常特殊的情况。

如您的问题中所述,要稍微改善解码特殊字符(变音符号、重音字符等)的结果,您可能需要根据PDF 规范的Annex D Character Sets and Encodings添加翻译。

详细地:

decodePDF 遍历PDF 中的对象并选择流对象。在这里,它完全忽略了这些对象是否仍在使用中(即在文档中经常看到来自所有修订的修订流)。

从这些流中,它使用Length1TypeSubType键删除所有内容。(好的)意图是删除包含页面内容以外的其他内容的流。不幸的结果是对象流也被删除了。对象流是自 PDF 1.5 以来 PDF 规范的一部分,并捆绑了多个其他任何类型的对象,包括流;它们提供比常规顶级对象更好的压缩属性。因此,使用此功能的文档内容在这里丢失。

在剩余的流中,它检查它们是否包含文本对象。如果它们包含文本对象BT ... ET,则这些对象的内部内容由getDirtyTexts处理。如果没有,则由getCharTransformations处理。

getDirtyTexts收集文本运算符TJTj的字符串参数;一方面,这意味着它忽略了文本运算符'"的参数,此外还忽略了有关这些字符串如何相互定位的任何信息。广泛使用字距调整信息的文档内容和使用此类操作的文档的内容而不是字符串中的空格来分隔单词, 因此以后可能完全不可读. 此外, 选择字体的操作在这里被丢弃 --- 但由于流根本没有连接到它们各自的资源对象, 字体信息无法匹配无论如何...

getCharTransformations假定流是ToUnicode映射流,并将所有这些流的所有映射添加到单个映射中。作为多个ToUnicode流,如果存在,很可能属于不同的字体并且可能具有完全不同的映射,将它们全部放在一个映射中会丢失大量映射信息,除非所讨论的字体被安排为具有不重叠的字符标识符范围。 ..他们为什么要这样做!

现在decodePDF调用getTextUsingTransformations来处理这两个方法的结果。它遍历getDirtyTexts提取的字符串。如果它们是十六进制编码的,它们将被解码,然后使用getCharTransformations提取的映射进行翻译。如果它们不是十六进制编码的,它们将按原样复制而无需任何进一步的翻译。

因此,十六进制编码字符串的内容是根据一些 ToUnicode 映射解释的,该映射可能是也可能不是与它们一起使用的相应字体相关联的编码,并且非十六进制编码字符串的内容按原样使用,完全忽略它们各自字体的编码。

因此,从本质上讲,该类唯一可以成功使用的 PDF 必须对与非十六进制编码字符串一起使用的字体使用标准编码(直到字符代码 127 的标准编码是 ASCII-ish)和具有相同编码的编码与十六进制编码字符串一起使用的字体的字符代码范围重叠的映射。

要稍微改进从非十六进制编码字符串中解码特殊字符的结果,您可能需要根据PDF 规范的Annex D Character Sets and Encodings添加翻译。

于 2013-04-16T11:15:32.227 回答