我有一张从互联网下载的图像,以及使用 Chrome 打印页面功能从同一图像创建的 PDF。
当我压缩然后解压缩同一图像时,一切正常
const deflate = zlib.createDeflate();
const inp = fs.createReadStream('output.png');
const out = fs.createWriteStream('encoded.txt');
inp.pipe(deflate).pipe(out);
// file is deflated, great
const inflate = zlib.createInflate();
const input = fs.createReadStream('decoded.txt');
const output = fs.createWriteStream('decoded.png');
input.pipe(inflate).pipe(output);
// file is the same exact image as expected
但是当我对 pdf 图像执行相同操作时,它不起作用并且抛出不太有帮助未捕获错误:Zlib 错误 就这样。我建议图像格式错误,可能需要以某种方式将 PDF 中的元数据包含在图像中,但我不太确定它不起作用的确切原因是什么。
还有一个细节,我只是修剪图像流开始和结束之前和之后的所有行,以便它只读取此图像数据。
这是 pdf 中图像流对象之前的一些行
4 0 obj
<</Type /XObject
/Subtype /Image
/Width 1500
/Height 970
/ColorSpace [/ICCBased 5 0 R]
/BitsPerComponent 8
/Filter /FlateDecode
/Length 320983>> stream
有人可以建议我在这里缺少什么吗?
链接到pdf文件,但总的来说,我认为对于以这种方式创建的任何其他PDF来说,它应该以类似的方式工作
谢谢
在 PDF 中存储图像的方法有很多,但在最基本的层面上,有嵌入本机文件或引用其外部图像数据流(作为安全问题来避免,因此仅在封闭系统中使用)。
还有根据这个问题的位图,因为 PDF 无法支持嵌入的 PNG 或许多其他现代文件格式。
不支持的本机图像类型(例如 PNG)在导入时会转换为一两个压缩的原始像素图,这些像素图没有用于在提取时重新格式化的元数据。
pdf 中存储的图像没有密度,仅在元物理上(基于推测或抽象推理)描述为位乘以/宽度/高度/长度(压缩数据)。
要膨胀,您将位乘以高度乘以宽度以获得提取的尺寸,因此在本例中,即 1500 x 970 = 4365000 (4.2 MB) 作为无头像素图,然后可以将其保存为您希望的任何文件格式,例如与PNG 库。
更简单的方法是使用任何包含此类代码的命令行工具,并且 poppler
pdfimages
有多种输出格式,因此 -all
将尝试最佳匹配。
本例中的输出将是压缩后的 570,505 字节.png
或者
mutool extract
将产生 328,335 字节的更压缩输出。