2

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

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

书中的语言包括英语、德语、西班牙语和意大利语。在德国,大写是绝对关键的。它往往比小写更容易丢失大写属性。

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

我真的不知道在这里做什么。我已要求书的所有者将他所做的字体嵌入为子集,但问题仍然存在。我尝试将 pdf 文件保存为附言,然后通过蒸馏器运行它,这在很大程度上解决了问题,但在某些情况下,导致文本被替换为不同的字符或数字,显示为头骨。我知道 CID 字体可能会导致该问题,但我遇到过非 CID 字体具有相同结果的实例。

什么可能导致此问题?字体是子集还是完全嵌入的?有没有更好的方法将本机文件 (InDesign) 保存为 pdf 以实现更好的字体提取?它是否与非 unicode 字体有关,如果是这样,是否有不需要所有者选择不同字体的替代方法?

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

4

2 回答 2

2

这确实很好笑。OP 提供的示例 PDF 确实明显包含大写字符,其中一些仅大写行,一些混合大小写行,由 Adob​​e 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。但是,如果那是来自 Adob​​e 的软件,如果这是 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 代码中添加一些额外条件以仅删除错误的字体定义。

于 2013-07-23T07:47:37.953 回答
0

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

有没有更好的方法将本机文件 (InDesign) 保存为 pdf 以实现更好的字体提取?

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

您的 WELD-weld 问题可能是由于字体(如果它包含映射到相同字形的大写和小写字母)、使用 OpenType 功能(如 All Capitals),或者甚至是像在PDF格式。

于 2013-07-19T13:42:47.690 回答