Извлечение данных из потока /Filter/FlateDecode PDF в PHP
Я не могу расшифровать данные из потока, например:
56 0 obj
<< /Length 1242 /Filter /FlateDecode >>
stream
x]êΩnƒ Ñ{ûbÀKq¬æ\âê¢....(whole binary is omitted)
endstream
endobj
Я попытался изолировать двоичный контент (x]êΩnƒ Ñ{ûbÀKq¬æ\âê¢....
) в файле и в двоичной строке. Функция декодирования gzinflate($encripted_data)
отправляет мне ошибку декодирования, и я думаю, что это происходит из-за того, что закодированное содержимое не "дефлировано" или так.
В PDF Reference v 1.7, (six edition), на странице 67, я нашел описание фильтра /FlateDecode как:... Декомпретирует данные, закодированные с использованием метода сжатия zlib/deflate, воспроизводя исходный текст или двоичные данные
Мне нужно настоящее необработанное решение, aka php function или/и алгоритм, что делать с этим потоком "\ FlateDecoded".
Спасибо!
Ответы
Ответ 1
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
Колокольчики! Джингл-колокола!...
gzuncompress()
- решение
Ответ 2
Поскольку вы не указали, требуется ли вам доступ к одному распакованному потоку или если вам нужны все распакованные потоки, я предлагаю вам простой инструмент командной строки, который делает это за один раз для полный PDF: Jay Berkenbilt qpdf
.
Пример командной строки:
qpdf --qdf --object-streams=disable in.pdf out.pdf
out.pdf
можно затем проверить в текстовом редакторе (только встроенные профили ICC, изображения и шрифты все еще могут быть двоичными).
qpdf
также автоматически переупорядочит объекты и отобразит синтаксис PDF нормализованным образом (и сообщит вам в комментарии, каков был исходный идентификатор объекта де-сжатого объекта).
Если вам требуется повторно сжать файл (возможно, после его редактирования), просто запустите эту команду:
qpdf out-edited.pdf out-recompressed.pdf
(Возможно, вы увидите предупреждение, в котором говорится, что утилита пытается восстановить поврежденный файл....)
qpdf
является многоплатформенным и доступен из Sourceforge.
Ответ 3
Долгосрочно, но кто-то может оказаться полезным. В этом случае:
& Л; </Length 1242/Filter/FlateDecode → все, что вам нужно, это передать изолированную двоичную строку (так что в основном все между "потоком" и "endstream" ) на zlib.decompress:
import zlib
stream = b"êΩnƒ Ñ{ûbÀKq¬æ\âê" # binary stream here
data = zlib.decompress(stream) # Here you have your clean decompressed stream
Однако, если у вас /DecodeParms в вашем объекте PDF становится сложнее. Вам понадобится значение /Predictor и номер столбца. Для этого лучше используйте PyPDF2.
Ответ 4
Я просто использовал
import de.intarsys.pdf.filter.FlateFilter;
из jpod/source forge
и он хорошо работает
FlateFilter filter = new FlateFilter(null);
byte[] decoded = filter.decode(bytes, start, end - start);
байты прямо из файла pdf