使用 convert 将 .png 批量转换为 .pdf 时出现问题

使用 convert 将 .png 批量转换为 .pdf 时出现问题
convert /home/bill/TempScan/*.png  myfile.pdf

给出错误信息:

convert-im6.q16: not authorized `myfile.pdf' @ error/constitute.c/WriteImage/1037.

任何帮助,将不胜感激!

答案1

convert是一个强大的命令行工具,用于转换图形。它对 PDF 的支持由 Ghostscript 提供。由于Ghostscript 中的安全漏洞在 9.24 版之前,PDF 文件的使用convert已被阻止,作为一种权宜之计。自 Ghostscript 9.24 版以来,此问题已得到修复。虽然 Ghostscript 版本已更新为所有受支持的 Ubuntu 版本中的安全版本(目前从 Ubuntu 16.04 开始),但使用限制可能仍然存在。

策略文件为/etc/ImageMagick-6/policy.xml。您可以以 root 用户身份编辑该文件来更改策略。

消除所有使用限制

对于没有运行 Web 服务器的桌面用户,只需消除这些限制就足够了。为此,可以删除文件,但更好的做法是通过重命名来“移出文件”。使用此命令,您将重命名文件。因此,所有策略都将被解除,但您仍然可以根据需要恢复:

sudo mv /etc/ImageMagick-6/policy.xml /etc/ImageMagick-6/policy.xmlout

要恢复原来的情况,只需重命名回原来的名称:

sudo mv /etc/ImageMagick-6/policy.xmlout /etc/ImageMagick-6/policy.xml

请注意,移出策略文件会降低系统安全性。

仅消除合并为 PDF 的限制

对于您的具体情况,gene_wood 在评论中指出可以通过注释掉一行来有选择地放宽处理 PDF 文件的策略:

<policy domain="coder" rights="none" pattern="PDF" />

编辑该文件,并在此行周围放置注释标记以禁用此规则:

<!-- <policy domain="coder" rights="none" pattern="PDF" /> -->

如果您不想消除所有安全策略,这就是可行的方法。

答案2

作为钒贴,您必须更改 ImageMagick 策略。

sudo vim /etc/ImageMagick-6/policy.xml

并替换行

<policy domain="coder" rights="none" pattern="PDF" />

<policy domain="coder" rights="read|write" pattern="PDF" />

如果只允许写入,而不允许读取,也可以擦除read|上面那行的部分。


顺便说一句,对于那些对 ImageMagick 漏洞感兴趣的人,这里有 2 个信息链接:

答案3

我不会重新放松 ImageMagick 的安全限制,而是使用img2pdf

它是专门为这种用例而设计的。

如果您的优先事项如下(按此顺序),则应使用 img2pdf:

  • 始终无损:PDF 中嵌入的图像的每个像素的颜色信息与输入始终完全相同
  • 小的:如果可能的话,输入图像和输出 PDF 之间的文件大小差异仅仅是 PDF 容器本身的开销
  • 快速地:如果可能的话,输入图像会直接粘贴到 PDF 文档中,而无需对像素数据进行任何耗费 CPU 的重新编码

传统的转换软件(例如 ImageMagick)会执行以下操作之一:

  1. 不是无损的,因为有损重新编码为 JPEG
  2. 不会太小,因为使用浪费的原始像素数据平面编码
  3. 由于输入数据被重新编码,所以速度不快

不需要重新编码输入的另一个优点(在大多数情况下)是,img2pdf 能够处理比其他软件大得多的输入,因为原始像素数据不需要加载到内存中。

这应该是等效的命令:

img2pdf --out myfile.pdf /home/bill/TempScan/*.png 

如果由于某种原因您无法这样做(例如无法安装新软件包),无损转换的另一种潜在途径是将convert您的图像转换为多页 TIFF 文件,然后使用tiff2pdflibtiff 工具。

答案4

这是一个更方便的方法,可以自动获取 policy.xml 文件的位置并对它们全部执行搜索/替换:

for file in `convert -list policy | grep "Path:" | grep -v built | sed 's/Path: \(.*\)/\1/g'`; do sed -i 's/domain="coder" rights="none" pattern="PDF"/domain="coder" rights="read|write" pattern="PDF"/g' $file; done

相关内容