我正在尝试使用找到的代码here从PDF文件中提取文本。该代码使用zlib库。
AFAICT程序的工作原理是在pdf文件中找到文本“stream”和“endstream”的出现之间的内存块。然后这些块被zlib充气。
代码在一个示例pdf文档上完美运行,但在另一个示例中,zlib的inflate()
函数每次调用时都会返回-3(Z_DATA_ERROR)。
我注意到,失败的pdf文件被设置为在Adobe Reader中打开时没有“复制”选项。这可能与inflate()
错误有关吗?...如果是,是否可以解决问题?
下面的代码段 - 请参阅注释
//Now use zlib to inflate:
z_stream zstrm; ZeroMemory(&zstrm, sizeof(zstrm));
zstrm.avail_in = streamend - streamstart + 1;
zstrm.avail_out = outsize;
zstrm.next_in = (Bytef*)(buffer + streamstart);
zstrm.next_out = (Bytef*)output;
int rsti = inflateInit(&zstrm);
if (rsti == Z_OK)
{
int rst2 = inflate (&zstrm, Z_FINISH); // HERE IT RETURNS -3
if (rst2 >= 0)
{
//Ok, got something, extract the text:
size_t totout = zstrm.total_out;
ProcessOutput(fileo, output, totout);
}
}
编辑:我通过名为zamzar的在线pdf到文本转换器测试了“加密”pdf中的文本提取,结果文本文件非常完美。所以要么zamzar有一些超级解密系统......或者也许它不是很难。
编辑:刚发现A-pdf也没有问题地转换为文字。
答案 0 :(得分:5)
PDF中的流不需要用flate编码。它们可以编码为:
而且(惊讶,惊讶)这些方法中的任何一种都可以叠加在一起!
如果没有复制选项,则可能是使用所有者密码加密而没有用户密码。这允许作者创建应该由读者尊重的访问权限,包括:
这种从PDF中获取文本的特殊方法充满了错误,我可以为您提供一组文档,由于字体重新编码,我们无法使用您的方法文本,奇怪的位置,形成XObjects,异常转换等等。
要做到这一点,您需要一套更好的工具,这些工具不会对PDF文档的实际格式和结构视而不见。 iText会这样做,DotImage会这样做。
为了让您了解问题的范围,我在Acrobat 1.0中编写了原始文本搜索代码,并且使用了所有可用的内部工具,我花了好几个月的时间来完成它并且代码包含了该功能查找异常,非直线方向(思考地图),处理连字,重新编码,非罗马字体等文本。在我编写代码的同时,还有另一位工程师专门花了几年的时间编写了一个名为Wordy的代码,为全文提取和索引编写类似(但更复杂)的代码(有关详细信息,请参阅this answer关于Wordy)。
答案 1 :(得分:1)
如果没有“复制”选项,则pdf被加密,流也是如此。普通的zlib不起作用,你必须首先解密pdf,现在你正在使用一个合适的库来提取文本,需要注意很多编码,而不是一切都是win ansi。
答案 2 :(得分:-3)
这可能是因为标题与文档不同,因此请参阅相关问题ZLib Inflate() failing with -3 Z_DATA_ERROR。