在 PHP 中从 /Filter /FlateDecode PDF 流中提取数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11731425/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 01:57:30  来源:igfitidea点击:

Data extraction from /Filter /FlateDecode PDF stream in PHP

phppdfdecode

提问by Ruben Kazumov

I can not decrypt the data from the stream like:

我无法从流中解密数据,例如:

    56 0 obj 
    << /Length 1242 /Filter /FlateDecode >>
    stream
    x]êΩn? ?{?bàKq??\aê¢....(whole binary is omitted)
    endstream
    endobj

I tried isolate the binary content (x]êΩn? ?{?bàKq??\aê¢....) in a file and in a binary string. Decoding function gzinflate($encripted_data)sends me error of decoding, and I think it happens because encoded content in not "deflated" or so.

我尝试隔离x]êΩn? ?{?bàKq??\aê¢....文件和二进制字符串中的二进制内容 ( )。解码功能gzinflate($encripted_data)向我发送解码错误,我认为这是因为编码内容未“压缩”左右。

In PDF Reference v 1.7, (six edition), on a page 67, I found the description of /FlateDecode filter as: ...Decompresses data encoded using the zlib/deflate compression method, reproducing the original text or binary data

在 PDF Reference v 1.7, (6 edition), 在第 67 页,我发现 /FlateDecode 过滤器的描述为:...解压缩使用 zlib/deflate 压缩方法编码的数据,再现原始文本或二进制数据

I need real raw solution, aka php function or/and algorithm what to do with this "\FlateDecoded" stream.

我需要真正的原始解决方案,又名 php 函数或/和算法如何处理这个“\FlateDecoded”流。

Thank You!

谢谢你!

采纳答案by Ruben Kazumov

header('Content-Type: text');           // I going to download the result of decoding
$n = "binary_file.bin";                 // decoded part in file in a directory
$f = @fopen($n, "rb");                  // now file is mine
$c = fread($f, filesize($n));           // now I know all about it 
$u = @gzuncompress($c);                 // function, exactly fits for this /FlateDecode filter
$out = fopen("php://output", "wb");     // ready to output anywhere
fwrite($out, $u);                       // output to downloadable file

Jingle bells! Jingle bells!...

铃儿响叮当!铃儿响叮当!...

gzuncompress()- the solution

gzuncompress()- 解决方案

回答by Kurt Pfeifle

Since you didn't tell if you need to access onedecompressed stream only or if you need all streams decompressed, I'll suggest you a simple commandline tool which does it in one go for the complete PDF: Jay Berkenbilt's qpdf.

由于您没有说明是只需要访问一个解压缩的流还是需要对所有流进行解压缩,我建议您使用一个简单的命令行工具,它可以一次性完成完整的 PDF:Jay Berkenbilt 的qpdf.

Example commandline:

示例命令行:

 qpdf --qdf --object-streams=disable in.pdf out.pdf

out.pdfcan then be inspected in a text editor (only embedded ICC profiles, images and fonts could still be binary).

out.pdf然后可以在文本编辑器中检查(只有嵌入的 ICC 配置文件、图像和字体仍然可以是二进制的)。

qpdfwill also automatically re-order the objects and display the PDF syntax in a normalized way (and telling you in a comment what the original object ID of the de-compressed object was).

qpdf还将自动重新排序对象并以规范化的方式显示 PDF 语法(并在注释中告诉您解压缩对象的原始对象 ID 是什么)。

Should you require to re-compress the file again (maybe after you edited it), just run this command:

如果您需要再次重新压缩文件(可能在您编辑之后),只需运行以下命令:

 qpdf out-edited.pdf out-recompressed.pdf

(You may see some warning message, telling that the utility was attempting to repair a damaged file....)

(您可能会看到一些警告消息,表明该实用程序正在尝试修复损坏的文件....)

qpdfis multi-platform and available from Sourceforge.

qpdf是多平台的,可从 Sourceforge 获得

回答by Belial

Long overdue, but someone might find it helpful. In this case: << /Length 1242 /Filter /FlateDecode >> all you need is to pass the isolated binary string (so basically everything between "stream" and "endstream") to zlib.decompress:

姗姗来迟,但有人可能会发现它有帮助。在这种情况下: << /Length 1242 /Filter /FlateDecode >> 所有你需要的是将隔离的二进制字符串(所以基本上是“stream”和“endstream”之间的所有内容)传递给 zlib.decompress:

import zlib
stream = b"êΩn? ?{?bàKq??\aê"  # binary stream here
data = zlib.decompress(stream) # Here you have your clean decompressed stream

However, if you have/DecodeParms in your PDF object thing become complicated. You will need the /Predictor value and columns number. Better use PyPDF2 for this.

但是,如果您的 PDF 对象中有/DecodeParms,事情就会变得复杂。您将需要 /Predictor 值和列数。最好为此使用 PyPDF2。

回答by Gordon Bartel

i just used

我刚用过

import de.intarsys.pdf.filter.FlateFilter;

from jpod / source forge and it works well

来自 jpod / source forge 并且运行良好

FlateFilter filter = new FlateFilter(null);
byte[] decoded = filter.decode(bytes, start, end - start);

the bytes are straight from the pdf file

字节直接来自 pdf 文件