我需要处理一些PDF文件。该任务包括与另一个图像文件交换给定的图像文件。我的第一个问题是如何在批处理过程中从命令行替换 PDF 图像。接下来我将尝试解决其他问题,例如如何识别我需要替换的图像(因为 PDF 文件可能有多个图像)。但首先我想解决第一个问题:如何用另一个图像替换 PDF 中的图像。
我读过有关 poppler-utils 和 pdftk 的内容,但据我所知,这些工具都不允许将图像替换为 PDF。
答案1
好吧……我认为pdflatex
这是这里缺失的部分。
OP 表示他已经调查了poppler-utils
和pdftk
。让我补充一下pdfimages
。这些pdflatex
都是解决方案的组成部分。
pdfimages -f 4 -l 20 -j -png target.pdf imageroot
在上面的示例代码中,pdfimages
浏览第 4 页到第 20 页target.pdf
,并将所有图像提取到名称以 开头的文件中imageroot
。
poppler-utils
提供pdftotext
.我推荐这个-layout
选项,它可以很好地保持文档的可读性。
pdftotext -layout $1.pdf $1.txt
OP 反对imagemagick
提供的解决方案盾龙是图像没有可提取的文本。使用我概述的实用程序,OP 现在将拥有所有图像以及所有提取的文本,并且该-layout
选项保留页码和内容。 OP 可以识别正确的文本页面并将其放入一个.tex
以指令结尾的文件中%includegraphics
,并通过文件名引用替换图片。然后,您pdflatex
将得到一个新的单页 .pdf,并使用 .pdf 插入文档的其余部分pdftk
。如果您知道图像在原始页面文本中的位置,%includegraphics [h]
则可以将图像放置在正确的位置。
答案2
如果一个简单的 python 脚本足以满足您的需求,那么解决方案很简单pdfrw 库。
一个简单的工作示例:
#!/bin/python
import pdfrw
# Read the example pdf file originating from:
# https://getsamplefiles.com/download/pdf/sample-3.pdf
reader = pdfrw.PdfReader('sample-3.pdf')
# Opening the new image file originating from:
# https://www.picserver.org/assets/library/2020-10-31/originals/example1.jpg
with open('example1.jpg', 'rb') as f:
# Overwriting the desired image in the original pdf structure.
reader.Root.Pages.Kids[0].Resources.XObject['/X9'].stream = f.read().decode('latin')
# Write the modified pdf file out.
pdfrw.PdfWriter('sample-3_out.pdf', trailer=reader).write()
在 pdf 结构中找到正确的图像元素可能有点棘手,但有一个非常有用的工具可以检查 pdf 结构,称为pdf分析仪。
将 pdfalyze 与 -t 标志一起使用以获取树视图,或使用 -r 标志以获取丰富的树视图,如下所示:
pdfalyze --maximize-width -r sample-3.pdf | less -R
据我所知,/Filter /DCTDecode
pdf 结构中的 表示 jpg 图像数据,/Filter /FlateDecode
表示 gzip 压缩数据。一个流数据可以有多个过滤器,并且过滤器的数量比这两个还要多。
答案3
为了澄清一点,您是否有大量 .pdf 文件,以及其中一些文件中需要替换的图像名称列表,但您需要一种快速方法来查找每个需要替换的图像,而无需打开每个 .pdf 文件。 pdf 文件在目录中吗?
如果我处于你的境地并且无法投入足够的时间来寻找/开发基于代码的解决方案,我会尝试在 Inkscape 中进行一些批处理。这超出了我的想象,但是...
- 复制您正在使用的所有 pdf 文件
- 在 Inkscape 中打开 pdf,然后使用“变换/缩放”命令来减小尺寸(并减小文件大小)。测试一下您可以将 pdf 页面缩小到多小,并且仍然可以识别图像。
- 使用批处理命令来转换/缩放复制目录中所有 pdf 的文件大小。您还可以使用批处理来启用某种图像优化或其他处理来减小每个文件的大小。
- 在 Inkscape 中一次打开 20 张左右的图像(拖放?),然后目视扫描需要替换的图像。
- 通过单击 Inkscape 中的 pdf,您应该能够获取文件名或根据其堆叠顺序确定它,然后打开并交换原始图像。
在最坏的情况下,繁重的工作=播客时间。