ImageMagick PDF 与图片互转
用 ImageMagick 把 PDF 页面转成图片,控制渲染分辨率、提取指定页,并解决所有人都会遇到的两个报错:PDF 安全策略和缺少 Ghostscript。
这是 ImageMagick 最常失败的任务,而且几乎从来不是你的命令有问题。两个环境问题占了几乎全部的失败案例,下面都讲清楚。
把 PDF 转成印刷分辨率的 PNG
magick -density 300 input.pdf -background white -alpha remove \
-quality 100 page-%02d.png
这里有三个细节很关键:
-density必须写在输入文件名前面。 它是告诉 Ghostscript 用什么分辨率去光栅化。写在后面的话,PDF 已经按默认 72 DPI 渲染完了,你只是在放大一张糊图。- PDF 页面的背景是透明的。 直接转 JPEG 会变成黑色,所以要压到白底上。
- 多页 PDF 需要计数器(比如
%02d),否则 ImageMagick 会自己加后缀。
该用多大的 density
| 用途 | DPI |
|---|---|
| 屏幕预览、缩略图 | 72–150 |
| 网页展示、阅读 | 150–200 |
| 印刷、OCR | 300–400 |
DPI 对像素数量的影响是平方级的。A0 海报按 300 DPI 渲染大约是 4 万像素宽,会直接撞上 ImageMagick 的资源限制。DPI 要按页面尺寸来定,不要凭习惯。
只导出某一页
magick -density 300 'input.pdf[0]' -quality 100 cover.png
方括号里的页码从 0 开始,所以 [0] 是第一页,[0-3] 是前四页。引号是必须的,否则 shell 会把方括号当成通配符去展开。
图片合成 PDF
magick page-*.jpg -quality 92 output.pdf
文件名要补零对齐 —— shell 按文本排序,page-10.jpg 会排在 page-2.jpg 前面。
ImageMagick 会重新编码每一页,所以这样合出来的扫描 PDF 往往比原图还大。要把已有 JPEG 无损地拼成 PDF,img2pdf 是更合适的工具。
报错:not authorized by the security policy 'PDF'
你的命令没问题 —— 是 policy.xml 把它拦住了。2018 年 Ghostscript 爆出一系列漏洞后,各发行版开始默认在 ImageMagick 里禁用 PDF、PS、EPS 和 XPS。先找到这个文件:
magick -list policy
打开它打印出的路径(常见是 /etc/ImageMagick-7/policy.xml),删掉或注释掉这几行:
<policy domain="coder" rights="none" pattern="PDF" />
<policy domain="coder" rights="none" pattern="PS" />
<policy domain="coder" rights="none" pattern="EPS" />
只有在你信任这些 PDF 时才这么改。 如果是给陌生人上传的文件做转换的服务器,这条策略是有意义的 —— 保留它,改用沙箱化的 pdftoppm(poppler-utils)。完整说明 →
报错:no images defined 或 FailedToExecuteCommand 'gs'
没装 Ghostscript。ImageMagick 自己解不了 PDF —— 它是去调用外部的 gs,找不到就会读入 0 张图,然后抱怨没东西可写。
apt install ghostscript # Debian / Ubuntu
brew install ghostscript # macOS
dnf install ghostscript # Fedora