使用Poppler(C++)从PDF中提取文本

nic*_*ico 3 c++ pdf text-extraction poppler

我正试图通过Poppler及其(缺乏)文档.

我想做的是一个非常简单的事情:打开一个PDF文件并阅读其中的文本.我接下来要处理文本,但这并不重要.

所以...我看到了这个poppler_page_get_text功能,它有点工作,但我必须指定一个选择矩形,这不是很方便.是不是只有一个非常简单的函数可以按顺序输出PDF文本(可能是逐行?).

pli*_*nth 9

您应该能够将选择矩形设置pageSize/MediaBox为页面的选择矩形并获取所有文本.

我说应该是因为在你开始想知道为什么你poppler_page_get_text会对输出感到惊讶之前,你应该知道文本如何在页面上布局.所有图形都使用以修复后符号表示的程序在页面上排列.要呈现页面,此程序在空白页面上执行.

程序中的操作可以包括改变颜色,位置,当前变换矩阵,绘制线,贝塞尔曲线等.文本由一系列文本运算符布局,这些运算符总是被BT(开始文本)和ET(结束文本)括起来.文本放置在页面上的方式和位置由生成PDF的软件自行决定.例如,对于打印驱动程序,代码响应GDI调用DrawString并将其转换为文本绘制操作.

如果运气好的话,页面上的文字将按照合理的字体使用顺序排列,但许多生成PDF的程序并不那么友好. Psroff,例如喜欢先放置所有纯文本,然后是斜体文本,然后是粗体文本.单词可能会也可能不会按阅读顺序排列.字体可以重新编码,以便'a'映射到'{'或等等.那么你可能有多个字符由单个字形取代连字-最常见的是ae,oe,fi,fl,和ffl.

有了所有这些,提取文本的过程显然是非平凡的,所以如果您发现文本提取质量差,请不要感到惊讶.

我曾经在Acrobat 1.0和2.0中使用文本提取工具 - 这是一个真正的挑战.


yve*_*mes 5

只是为了记录,我现在正在用这个小程序使用poppler

#include <iostream>

#include "poppler-document.h"
#include "poppler-page.h"
using namespace std;

int main()
{
    poppler::document *doc = poppler::document::load_from_file("./CMI2APIDocV1.4.pdf");
    const int pagesNbr = doc->pages();
    cout << "page count: " << pagesNbr << endl;

    for (int i = 0; i < pagesNbr; ++i)
        cout << doc->create_page(i)->text().to_latin1().c_str() << endl;
}

// g++ -I/usr/include/poppler/cpp/ -c poppler.cpp
// g++ -I/usr/include/poppler/cpp poppler.o  /usr/lib/x86_64-linux-gnu/libpoppler-cpp.a /usr/lib/x86_64-linux-gnu/libpoppler.a /usr/lib/x86_64-linux-gnu/liblcms2.so     /usr/lib/x86_64-linux-gnu/libfontconfig.a /usr/lib/x86_64-linux-gnu/libjpeg.a /usr/lib/x86_64-linux-gnu/libfreetype.a     /usr/lib/x86_64-linux-gnu/libexpat.a /usr/lib/x86_64-linux-gnu/libz.a
Run Code Online (Sandbox Code Playgroud)

到目前为止,我对结果非常满意,除了纯文本中的数组和“电子表格”恢复,有时单个单元格可能跨越多行。(如果有人知道如何避免这种情况?)