关于从 PDF 文件中提取简单文本有许多问题(有些已回答,有些未回答)。 Stackoverflow 有助于指出 PDF Adob​​e 文档在解析过程中非常清楚地检测对象:即,在使用 CGPDFScanner 时,应该使用“BT”和“ET”PDF 引用运算符来构造回调。

苹果文档显示了一个回调示例:

static void op_BT (CGPDFScannerRef s, void *info) {
    const char *name;
    if (!CGPDFScannerPopName(s, &name))
        return;
    printf("BT /%s\n", name);
}

并且,在其他 CGPDFScanner 命令中,上述回调是通过首先创建:
myTable = CGPDFOperatorTableCreate();
CGPDFOperatorTableSetCallback (myTable, "BT", &op_BT);

到目前为止一切都很好,但 Apple 文档似乎并没有帮助像我这样的中低级程序员理解下一步:除了识别文本块(大概在 BT 和 BE 回调之间?)之外,还有哪些步骤/行需要在回调期间/内/外将识别的文本块捕获到 NSString 中吗?

非常感谢。

最佳答案

您应该做的第一件事是下载 PDF 引用。现在,这是一个 ISO 标准,但您可以下载 Acrobat SDK ( http://www.adobe.com/devnet/acrobat.html ),其中包含一个 Adob​​e 副本,同样可以为您服务。

阅读第 9 章。它会教您一方面需要了解文本运算符(Tj、'、”、TJ),另一方面需要了解字体和编码。

文本运算符是您可以拦截的运算符,用于向 PDF 文档添加“字符串”;虽然所有文本操作符都必须出现在 BT 和 ET 块之间,但我认为拦截这些 BT 和 ET 块本身对您没有多大帮助。

字体很重要,因为它们将定义这些运算符使用的字节如何对应于实际 (Unicode) 字符。因此,如果您想推导出从 PDF 文件中获得的字节的含义,您需要知道如何使用字体来推导该含义。

补充几点:

  • 不要假设 BT 和 ET 对应于实际的文本块或段落,因为您可能从 InDesign 或 Word 等应用程序中了解到它。一个文本块可能包含整个页面或单个字符(或什么都不包含)。
  • 还有文本状态运算符,用于确定文本在页面上的显示方式。例如,有一些方法可以绘制不可见的文本;您可能希望也可能不希望提取这种类型的文本。如果不这样做,则需要支持足够多的文本状态运算符,以便区分。

  • 不是一个小任务:)

    查看示例 PDF 后更新

    因为在评论中问题被提炼为指示特定类型的 PDF 文件的文本提取,让我添加一些额外的信息。

    1) 查看您引用的 PDF 文件,您将无法跳过字体/编码问题。示例 PDF 文件中的字体是子集化的,这意味着您在 PDF 页面描述中没有“明文”,而是必须通过用于获取有意义文本的字体编码进行映射的索引。

    2)如果您查看pdfToolbox的以下输出,则可以提取文本(警告,我与此工具有很大的关联):
    <page id="33">
        <words>
            <word txt="Senator">
                <parts>
                    <part tlh="28.3481" tlv="868.534" trh="55.4455" trv="868.534" blh="28.3481" blv="859.902" brh="55.4455" brv="859.902"></part>
                </parts>
            </word>
            <word txt="House,">
                <parts>
                    <part tlh="57.5305" tlv="868.534" trh="82.123" trv="868.534" blh="57.5305" blv="859.902" brh="82.123" brv="859.902"></part>
                </parts>
            </word>
            <word txt="85">
                <parts>
                    <part tlh="84.208" tlv="868.534" trh="92.548" trv="868.534" blh="84.208" blv="859.902" brh="92.548" brv="859.902"></part>
                    </parts>
            </word>
    

    毫无疑问,还有其他工具可以提供类似(或更好)的结果,因此单独提取文本应该是可行的。

    最大的问题是以正确的顺序找到您感兴趣的文本。我在这里使用的提取给出了每个“单词”的文本及其在页面上的位置(边界框)。当你到达表格时,当我查看 XML 时,挑战将是哪个文本属于哪个表格单元格,行和列在哪里结束等等......

    在某种程度上,这个问题比简单检测文本行的问题更难,因为您正在处理一个非常密集的表格(而我的问题主要是一维的(将所有内容收集在同一行上)这个问题是二维的.

    关于objective-c - 使用 CGPDFScanner 仅从 PDF 文件中提取文本,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30186577/

    10-14 23:09
    查看更多