这确实很好笑。OP 提供的示例 PDF 确实明显包含大写字符,其中一些仅大写行,一些混合大小写行,由 Adobe Reader 提取为小写字符。
你想知道
什么可能导致此问题?
作为一个例子,让我们看看这是如何发生的Pelle Più bella
在页面内容中,该短语实际上看起来像大写字母的视觉表示:
/T1_0 1 Tf
-0.025 Tc 12 0 0 12 379.5354 554.8809 Tm
(PELLE PI\331 BELLA)Tj
查看使用的字体T1_0(一个 DIN-Bold 子集),我们看到它声称使用WinAnsiEncoding,这也将页面流中的这些字符代码解释为大写字母
但是字体也有一个ToUnicode映射,这个映射映射
<41> <0061> — 'A' → a
<42> <0062> — 'B' → b
<43> <0043> — 'C' → C
<44> <0044> — 'D' → D
<45> <0065> — 'E' → e
<49> <0069> — 'I' → i
<4C> <006C> — 'L' → l
<4D> <004D> — 'M' → M
<4E> <006E> — 'N' → n
<50> <0050> — 'P' → P
<52> <0072> — 'R' → r
<53> <0053> — 'S' → S
<54> <0074> — 'T' → t
<D9> <00F9> — 'Ù' → ù
(我只从 WinAnsiEncoding 中代表大写字母的字符代码中提取映射。)
有没有更好的方法将本机文件 (InDesign) 保存为 pdf 以实现更好的字体提取?
抱歉,我不是很喜欢 InDesign。但是,如果那是来自 Adobe 的软件,如果这是 InDesign 中的错误或其导出为 PDF,我会感到惊讶。是否可能是 InDesign 文件中有一些信息将PELLE PIÙ BELLA标记为Pelle Più bella,然后 InDesign 在 PDF 导出中将其转换为此 ToUnicode 映射?
它是否与非 unicode 字体有关,如果是这样,是否有不需要所有者选择不同字体的替代方法?
在您的示例文档中,共有三种字体,它们都有一个编码条目WinAnsiEncoding,它们都是嵌入的子集,但只有两种具有如此有趣的ToUnicode映射,DIN-Medium 和 DIN-Bold,而 Helvetica 没有ToUnicode映射。所以它在某种程度上与字体有关。具体如何我不能说。
对于您的示例文档,一种解决方法是从字体字典中删除ToUnicode映射。
例如,使用 Java 和 iText 库,您可以这样做:
PdfReader reader = new PdfReader(INPUT);
for (int i = 1; i <= reader.getXrefSize(); i++)
{
PdfObject obj = reader.getPdfObject(i);
if (obj != null && obj.isDictionary())
{
PdfDictionary dic = (PdfDictionary) obj;
if (PdfName.FONT.equals(dic.getAsName(PdfName.TYPE)))
{
dic.remove(PdfName.TOUNICODE);
}
}
}
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(OUTPUT));
stamper.close();
reader.close();
在此操作之后,Adobe Reader 文本提取结果
PELLE PIÙ BELLA
这显然只适用于示例文档中的情况。
如果在您的其他文档中有混合字体,其中一些需要它们各自的ToUnicode映射来进行文本提取,而另一些则像上面的问题字体,您可能希望在 Java 代码中添加一些额外条件以仅删除错误的字体定义。