PDF文本提取问题 - 字体/大写不一致

时间:2013-07-19 03:45:54

标签: pdf character-encoding adobe-indesign text-extraction true-type-fonts

我正在尝试从pdf书中提取文本,并继续运行一个问题,即复制文本的某些部分在粘贴到文本文档时无法保留正确的大小写属性。我有权复制该书,并拥有使用所有必要字体的许可。起初我认为这个问题是由于没有嵌入字体引起的,但是我检查过并且所有字体看起来都是嵌入的子集。在pdf中,使用了超过100种具有以下属性之一的字体:

TrueType编码:Ansi TrueType(CID)编码:Identity-H 类型1(CID)编码:Identity-H 类型1编码:自定义

书中的语言包括英语,德语,西班牙语和意大利语。在德国,资本化绝对是至关重要的。它倾向于失去大写属性而不是低级。

错误的一个例子是:WELD - >焊接

我真的不知道该怎么做。我已经要求该书的所有者嵌入他作为子集完成的字体,但问题仍在继续。我已经尝试将pdf文件保存为postscript,然后通过distiller运行它正确的问题,但在某些情况下导致文本被替换为不同的字符或数字显示为头骨。我知道CID字体可能会导致问题,但我遇到过非CID字体具有相同结果的实例。

可能导致此问题的原因是什么?是字体是子集还是完全嵌入?有没有更好的方法将原生文件(InDesign)保存为pdf,以便更好地提取字体?是否与非unicode字体有关,如果有,是否有一个不需要所有者选择不同字体的替代方案?

非常感谢任何和所有的帮助。

2 个答案:

答案 0 :(得分:2)

这确实很有趣。 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。但是,如果这是InDesign中的错误或导出为PDF,那么来自Adobe的软件我会感到惊讶。可能是因为InDesign文件中有一些信息将PELLEPIÙBELLA标记为PellePiùbella,然后InDesign在PDF导出中转换为此ToUnicode映射?< / p>

  

是否与非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代码只删除有缺陷的字体定义中的地图。

答案 1 :(得分:0)

无需跳过PDF箍。它甚至不是一个好的文本交换格式。

  

有没有更好的方法将原生文件(InDesign)保存为pdf,以便更好地提取字体?

要求文件提供程序进行RTF导出。这将保留所有使用的字体和格式。

您的WELD焊接问题可能是因为字体(如果它包含映射到相同字形的大写和小写),使用OpenType功能(例如All Capitals),甚至是类似于仅创建错误的文本PDF中的流。