从PDF

时间:2015-06-03 14:23:50

标签: c++ pdf visual-studio-2008 zlib

我正在尝试使用找到的代码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也没有问题地转换为文字。

3 个答案:

答案 0 :(得分:5)

PDF中的流不需要用flate编码。它们可以编码为:

  1. 没有
  2. LZW
  3. Flate
  4. ASCII85
  5. Crypt(可能是几种不同算法之一)
  6. 而且(惊讶,惊讶)这些方法中的任何一种都可以叠加在一起!

    如果没有复制选项,则可能是使用所有者密码加密而没有用户密码。这允许作者创建应该由读者尊重的访问权限,包括:

    1. 修改文档内容
    2. 复制文字/图片
    3. 添加/编辑注释
    4. 打印
    5. 表格填写
    6. 组装文档(插入,删除页面,创建书签,缩略图)
    7. 高/低质量打印
    8. 这种从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