【问题标题】:Strange characters reading PDF with iTextSharp使用 iTextSharp 阅读 PDF 的奇怪字符
【发布时间】:2017-03-01 15:26:48
【问题描述】:

我正在使用 iTextSharp 阅读 PDF 文件。我尝试用这个简单的代码阅读第一页的全文:

var pdfReader = new PdfReader("<fileName>");
var pageText = PdfTextExtractor.GetTextFromPage(pdfReader, 1, new SimpleTextExtractionStrategy());

它返回一个这样的字符串:

"\0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 !\n\" \0 \0 \0 \ 0 \0 \0 # \0 $ \0 % \0 & $ \0 ' \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \ 0 \0 \0 \0 \0 \0 \0 !\n\" \0 \0 \0 (\n\0 \0 \0 ) \0 \0 * \0 + , \0 , \0 \0 & , \0 - \0 . # \0 \0 \0 & $ \0 , \0 /\n+ \0 & & \0 * 0 \0 1 .\n2 \0 3\n4 - \0 5 \0 \0 $ \0 \0 # \0 \0 \0 & $ \0 , \0 * & \0 \0 ' \0 .\n6\n\0 \0 \0 - \0 \0 \0 \0 & \0 \0 \0 \0 \0 \0 \0 , \0 # \0 \0 \0 & $ \0 , \0 \0 \0 & \0 # \0 \0 & $ ' ) & \ 0 \0 \0 \0 # \0 ' ' \0 7 - \0 $ \0 \0 7 \0 ' \0 , \0 8\n9 5 \0 \0 , \0 \0 $ $ \0 \ 0 \0 \0 \0 ' \0 \0 3\n\0 \0 \0 ) \0 \0 \0 \0 4 - \0 5 \0 \0 $ \0 \0 * & \0 \0 ' \0 .\n\0 \0 \0 \0 # \0 $ \0 $ \0 \0 ) \0 \0 \0 : 0 ; \0 ; \0 ? \0 ? \0 3 \0 (\n@\n\0 \0 # \0 $ \0 % \0 & $ \0 ’ \0 !3\n\0 ......"

我可以使用 Acrobat Reader 和浏览器阅读原始 PDF。该文件似乎是 PDF/A。

我使用的代码适用于其他 PDF。

iText 对这个标准有问题吗?

有人能指出正确的方向吗?

更新

从 Acrobat 复制/粘贴给我的文本损坏。我不认为这是 iTextSharp (5.5.10) 的问题。

更新

你可以试试这个文件: PDF Example

【问题讨论】:

  • AFAIK iTextSharp 适用于 PDF/A。当您提供任何其他 PDF 或 PDF/A 时,此方法是否正常工作?
  • 尝试自己读取文件的byte[] 内容并将其传递给PdfReader 构造函数。它必须与编码有关。
  • 你能用 Acrobat 提取文本吗?
  • 您没有提及您使用的是哪个版本的 iTextSharp。旧版本没有读取 toUnicode 映射。 iTextSharp 的标准没有任何问题,但一些声称是 PDF(页面上方的蓝丝带)的 PDF 并不是真正的 PDF/A 文件。您是否在 Acrobat 中对其进行了验证?
  • @Paulo - 从 Acrobat 复制/粘贴给我损坏的文本。

标签: c# pdf itext


【解决方案1】:

该文件不包含文本提取所需的信息。此外,该文件作为 PDF/A 文件无效。

文本提取信息

示例文件包含显示空表单的背景(位于表单 XObject 资源中)和填充值的前景(直接位于页面内容流中)。

XObject 形式的文本是使用 Type 3 字体绘制的,在其编码中没有标准编码或标准名称。其中也没有 ToUnicode 映射。

这意味着 文本绘图指令 在 XObject 形式中具有字节序列的参数,并且对于每个字节值,Type 3 字体对象提供一个包含简单绘图指令的流(使用线条的路径定义和曲线;路径填充指令),但没有哪个 Unicode 值对应于该字节值或绘图指令集的信息。

因此,PDF 查看器可以绘制页面,但他们无法正确地将 Unicode 字符串放入剪贴板,我们人类将从该绘图中读取,iTextSharp 也不能。

没有 OCR,没有合理的方法可以从表单中提取文本。


另一方面,直接在前景中的文本是使用具有标准编码 (WinAnsiEncoding) 的字体绘制的,因此可以被提取。因此,在 OP 代码的输出结束时,您会发现

\u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000

 ...

\u0000 \u0000 \u0000 x s \u0000 l t n q o x m l \u0000 z \u0000 ~ { \u0000 } } \u0000 l w x
2016
14874587948 DITTA PROVA SRL
CREMA CR 26013 VIA DANTE 17
011110
LPRGCM82T26D150H LEOPARDI GIACOMO
M 26 12 1982 CREMONA CR
MILANO MI F205
28 02 2017
DITTAP0101 / LEOGIA01001

即表单的填写值。

PDF/A 一致性

该文件确实声称是 PDF/A-1a,但检查它很快就会发现这是一个公然的谎言。例如。 Adobe Acrobat Preflight 说:

这些条目表明该文档实际上甚至没有尝试真正符合 PDF/A-a1,它只是声称如此。

【讨论】:

  • 感谢详尽的解释。是否可以使用 iTextSharp 重新创建 ToUnicode 映射?做这样的事情:font.FontDictionary.Put(PdfName.TOUNICODE,&lt;something here&gt;); 这可以解决问题吗?
  • 如果你能想出一个从字形代码到 Unicode 的字体映射,你可以做一些类似于那个字典的东西。但是你想从哪里得到这个映射呢?
  • 你是说即使我知道使用的字体也几乎不可能重新创建?
  • 如果您深入了解作为来源的字体文件并将其中的字形定义与那些 PDF Type 3 字体字符绘制说明进行比较,您可能会重新创建映射。但这并非微不足道,特别是因为说明不需要 100% 适合,可能会有小的偏差以防止容易识别。因此,虽然这个任务可能很有趣,但一个通用的解决方案将需要相当长的时间来实施。
  • GetToUnicode 返回一个流对象。 PDF 流必须是间接对象。因此,您必须将流添加到编写器 (obj = writer.AddToBody(STREAMOBJECT)) 并检索间接引用 (toUnicodeRef = obj.IndirectReference)。然后,您可以将此间接引用作为 ToUnicode 值添加到字体字典中。如果这不起作用,请自行提出堆栈溢出问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-28
  • 1970-01-01
  • 1970-01-01
  • 2013-03-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多