如何使用Ghostscript在PDF中删除重复对象?

4
使用命令行ghostscript,是否可以删除PDF中的重复嵌入对象(图像)并将它们替换为单个实例?
我有一个200多页的PDF文件,每页都有一个背景图像和一些较小的徽标。该文件非常大,因为相同的背景图像和徽标二进制文件被嵌入到每个单独的页面中,而不是嵌入一次,然后在每个页面上引用。我不是PDF的创建者,所以无法从根源上解决问题。
(我不想缩小或降低图像质量,也不想完全删除它们。)
2个回答

7
作为GhostScript的补充,pdfsizeopt在消除PDF中的重复嵌入对象(包括背景图像)方面表现出色,并且可以在文件被GhostScript处理之前或之后运行。但是,由于其依赖关系,将其包含在工作流程中有点棘手,并会创建大量临时文件。可在https://github.com/pts/pdfsizeopt(之前是https://code.google.com/p/pdfsizeopt/)找到它。我的200多页文档通过删除重复图像仅缩小到了40MB。

2
不,ghostscript(更具体地说是pdfwrite设备)不会替换图像XObject或内联图像,它不会检查它们是否相同。虽然这是可能的,但这意味着检查每个图像的每个字节,这可能会影响性能,因此我们目前不这样做。如果您想尝试修改源代码,我可以提供一些开始的建议。FWIW,许多其他对象都经过重复测试,但没有测试图像,仅仅因为读取和哈希大型图像需要很长时间。

1
我对你关于“这意味着检查每个图像的每个字节”的假设有所怀疑。难道不可能从图像流中创建哈希值,然后仅比较这些哈希值吗?(除非你认为创建哈希值也是“检查每个字节”,但在某种程度上它确实是...) - Kurt Pfeifle
是的,我确实将创建图像哈希视为“检查每个字节”,因为这就是你需要做的。目前,pdfwrite为大量不同的对象类型创建MD5哈希,正是出于这个目的,但它不会为图像创建哈希,因为读取多兆字节的数据通常是一个相当罕见的功能,因此被认为不值得。正如我所说,如果有人真的想要这样做,我可以提供指针来创建哈希的位置,如何确定现有哈希是否匹配以及如何用旧引用替换新图像。 - KenS
1
如果有人能接受这个挑战并得到你的帮助实现它,那会非常棒。因为OP所述的原因,存在许多“糟糕”的PDF文件太大了。 - Kurt Pfeifle
也许采用两步方法可以加快速度?首先检查长度相同的对象。在大多数情况下,图像的长度将不同。只有当另一个对象的大小匹配时,才进行哈希处理?(目前我没有更改源代码和构建gs的选项,但感谢您的提供。) - TeXter
然后您需要对两个图像进行哈希。考虑到我们必须解压缩并读取整个图像数据,因此通过MD5哈希算法处理图像数据所需的时间不是很长,但我认为采用两阶段方法会慢得多,因为在处理图像时进行哈希比事后进行哈希要快。尽管对于图像匹配的常见情况可能会更快。需要编写更多代码。 - KenS
好吧,这不是我希望得到的答案,但仍然是答案 :) - TeXter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接