我检查了您的文件,特别关注您的示例“मतद|र”,在文档页面的最上面一行中将其提取为“मतदरर”。
简而言之:
您的文档本身提供的信息例如:标题行中的字形“मतद|र”代表文本“मतदरर”。您应该向文档来源询问字体信息不会产生误导的文档版本。如果这不可能,您应该使用 OCR。
详细地:
第一页的顶行是通过页面内容流中的以下操作生成的:
/9 280 Tf
(-12"!%$"234%56*5) Tj
第一行选择名为的字体/9大小为 280(页面开头的操作将所有内容缩放 0.05 倍;因此,有效大小为您在文件中观察到的 14 个单位)。
第二行导致打印字形。使用该字体的自定义编码在括号之间引用这些字形。
当程序尝试提取文本时,它必须使用字体中的信息从这些字形引用中推断出实际字符。
字体/9PDF 第一页上的内容是使用以下对象定义的:
242 0 obj<<
/Type/Font/Name/9/BaseFont 243 0 R/FirstChar 33/LastChar 94
/Subtype/TrueType/ToUnicode 244 0 R/FontDescriptor 247 0 R/Widths 248 0 R>>
endobj
243 0 obj/CDAC-GISTSurekh-Bold+0
endobj
247 0 obj<<
/Type/FontDescriptor/FontFile2 245 0 R/FontBBox 246 0 R/FontName 243 0 R
/Flags 4/MissingWidth 946/StemV 0/StemH 0/CapHeight 500/XHeight 0
/Ascent 1050/Descent -400/Leading 0/MaxWidth 1892/AvgWidth 946/ItalicAngle 0>>
endobj
所以没有/编码元素,但至少有一个对 a 的引用/转Unicode地图。因此,提取文本的程序必须依赖于给定的/转Unicode映射。
引用的流/转Unicode从 (-12"!%$"234%56*5) 中提取文本时,包含以下感兴趣的映射:
<21> <21> <0930>
<22> <22> <0930>
<24> <24> <091c>
<25> <25> <0020>
<2a> <2a> <0031>
<2d> <2d> <092e>
<31> <31> <0924>
<32> <32> <0926>
<33> <33> <0926>
<34> <34> <002c>
<35> <35> <0032>
<36> <36> <0030>
(在这里您已经可以看到多个字符代码映射到相同的 unicode 代码点...)
因此,文本提取必须导致:
- = 0x2d -> 0x092e = म
1 = 0x31 -> 0x0924 = त
2 = 0x32 -> 0x0926 = द
" = 0x22 -> 0x0930 = र instead of |
! = 0x21 -> 0x0930 = र
% = 0x25 -> 0x0020 =
$ = 0x24 -> 0x091c = ज
" = 0x22 -> 0x0930 = र
2 = 0x32 -> 0x0926 = द
3 = 0x33 -> 0x0926 = द
4 = 0x34 -> 0x002c = ,
% = 0x25 -> 0x0020 =
5 = 0x35 -> 0x0032 = 2
6 = 0x36 -> 0x0030 = 0
* = 0x2a -> 0x0031 = 1
5 = 0x35 -> 0x0032 = 2
因此,从第一个文档页面的标题中提取的文本 iTextSharp(以及 Adobe Reader!)正是文档在其字体信息中声称的正确内容。
由于造成这种情况的原因是字体定义中的误导性映射信息,因此整个文档中存在误解也就不足为奇了。