在阅读PDF时搞砸了特殊字符

时间:2013-04-16 09:50:53

标签: php pdf web-deployment tcpdf

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

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

可以在此处找到课程:http://pastebin.com/PSmu03nH

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

1 个答案:

答案 0 :(得分:3)

简而言之:

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

如你问题中所提到的,为了轻松改善解码特殊字符(变音符号,重音字符......)的结果,你可能想要根据附件D 字符集和编码添加翻译。 PDF specification

详细说明:

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

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

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

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

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

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

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

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

要轻松改善非十六进制编码字符串中特殊字符的解码结果,您可能需要根据PDF specification的附件D 字符集和编码添加翻译。