如何使用 ImageMagick“转换”将 PDF 转换为 PNG 还是幽灵脚本?

发布于 2024-07-15 20:10:34 字数 490 浏览 7 评论 0原文

我正在尝试将 PDF 转换为 PNG 图像(至少是一个封面)。 我已经使用 pdftk 成功提取了 PDF 的第一页。 我正在使用 imagemagick 进行转换:

convert cover.pdf cover.png

这可行,但不幸的是 cover.png 渲染不正确(PDF 中的某些 alpha 对象未正确渲染)。 我知道 ImageMagick 使用 GhostScript 进行转换,如果我直接使用 gs 进行转换,我可以获得所需的结果,但我宁愿使用转换库,因为它还有我想利用的其他工具。

GhostScript 中的此命令完成了所需的图像:

gs -sDEVICE=pngalpha -sOutputFile=cover.png -r144 cover.pdf

我想知道是否有任何方法可以通过转换为 GhostScript 传递参数,或者我是否坚持直接调用 GhostScript?

I'm trying to convert a PDF to a PNG image (at least the cover of one). I'm successfully extracting the first page of the PDF with pdftk. I'm using imagemagick to do the conversion:

convert cover.pdf cover.png

This works, but unfortunately the cover.png comes through incorrectly rendered (some of the alpha object in the PDF aren't rendered properly). I know ImageMagick uses GhostScript to do the conversion and if I do it directly with gs I can get the desired results, but I'd rather use the convert library as it has other tools I'd like to leverage.

This command in GhostScript accomplishes the desired image:

gs -sDEVICE=pngalpha -sOutputFile=cover.png -r144 cover.pdf

I'm wondering is there any way to pass arguments through convert to GhostScript or am I stuck with calling GhostScript directly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

慢慢从新开始 2024-07-22 20:10:34

您可以使用一个命令行,其中两个命令(gsconvert)通过管道连接,前提是第一个命令可以将其输出写入 stdout,并且第二个命令可以读取它的输入来自标准输入。

  1. 幸运的是,gs 可以写入标准输出(... -o %stdout ...)。
  2. 幸运的是,convert 可以从标准输入读取(convert -background透明-output.png)。

问题已解决:

  • GS 用于处理特殊图像的 Alpha 通道,
  • convert 用于创建透明背景,
  • 管道用于避免在磁盘上写出临时文件。

完整解决方案:

gs -sDEVICE=pngalpha       \
   -o %stdout              \
   -r144 cover.pdf         \
   |                       \
convert                    \
   -background transparent \
   -                       \
    cover.png

更新

如果您希望每个 PDF 页面有一个单独的 PNG,您可以使用 %d 语法:

gs -sDEVICE=pngalpha -o file-%03d.png -r144 cover.pdf

这将创建 PNG 文件名为 page-000.pngpage-001.png、...(请注意,%d - 计数是从零开始的 - - file-000.png 对应于 PDF 的第 1 页,001 对应于第 2 页...

或者,如果您想保留透明背景,则为 100-页面 PDF,执行

for i in {1..100}; do        \
                             \
  gs -sDEVICE=pngalpha       \
     -dFirstPage="${i}"      \
     -dLastPage="${i}"       \
     -o %stdout              \
     -r144 input.pdf         \
     |                       \
  convert                    \
     -background transparent \
     -                       \
      page-${i}.png ;        \
                             \
done

You can use one commandline with two commands (gs, convert) connected through a pipe, if the first command can write its output to stdout, and if the second one can read its input from stdin.

  1. Luckily, gs can write to stdout (... -o %stdout ...).
  2. Luckily, convert can read from stdin (convert -background transparent - output.png).

Problem solved:

  • GS used for alpha channel handling a special image,
  • convert used for creating transparent background,
  • pipe used to avoid writing out a temp file on disk.

Complete solution:

gs -sDEVICE=pngalpha       \
   -o %stdout              \
   -r144 cover.pdf         \
   |                       \
convert                    \
   -background transparent \
   -                       \
    cover.png

Update

If you want to have a separate PNG per PDF page, you can use the %d syntax:

gs -sDEVICE=pngalpha -o file-%03d.png -r144 cover.pdf

This will create PNG files named page-000.png, page-001.png, ... (Note that the %d-counting is zero-based -- file-000.png corresponds to page 1 of the PDF, 001 to page 2...

Or, if you want to keep your transparent background, for a 100-page PDF, do

for i in {1..100}; do        \
                             \
  gs -sDEVICE=pngalpha       \
     -dFirstPage="${i}"      \
     -dLastPage="${i}"       \
     -o %stdout              \
     -r144 input.pdf         \
     |                       \
  convert                    \
     -background transparent \
     -                       \
      page-${i}.png ;        \
                             \
done
蔚蓝源自深海 2024-07-22 20:10:34

在所有可用的替代方案中,我发现 Inkscape 在将 PDF 转换为 PNG 时可以产生最准确的结果。 特别是当源文件具有透明层时,Inkscape 成功了 Imagemagick 和其他工具失败的地方。

这是我使用的命令:

inkscape "$pdf" -z --export-dpi=600 --export-area-drawing --export-png="$pngfile"

这里是在脚本中实现的:

#!/bin/bash

while [ $# -gt 0 ]; do

pdf=$1
echo "Converting "$pdf" ..."
pngfile=`echo "$pdf" | sed 's/\.\w*$/.png/'`
inkscape "$pdf" -z --export-dpi=600 --export-area-drawing --export-png="$pngfile"
echo "Converted to "$pngfile""
shift

done

echo "All jobs done. Exiting."

Out of all the available alternatives I found Inkscape to produce the most accurate results when converting PDFs to PNG. Especially when the source file had transparent layers, Inkscape succeeded where Imagemagick and other tools failed.

This is the command I use:

inkscape "$pdf" -z --export-dpi=600 --export-area-drawing --export-png="$pngfile"

And here it is implemented in a script:

#!/bin/bash

while [ $# -gt 0 ]; do

pdf=$1
echo "Converting "$pdf" ..."
pngfile=`echo "$pdf" | sed 's/\.\w*$/.png/'`
inkscape "$pdf" -z --export-dpi=600 --export-area-drawing --export-png="$pngfile"
echo "Converted to "$pngfile""
shift

done

echo "All jobs done. Exiting."
云巢 2024-07-22 20:10:34

要将 pdf 转换为图像文件,请使用以下命令:

对于 PNG gs -sDEVICE=png16m -dTextAlphaBits=4 -r300 -o a.png a.pdf

对于 JPG gs -sDEVICE=jpeg -dTextAlphaBits=4 -r300 -o a.jpg a.pdf

如果您有多个页面,请添加名称 %03d gs -oa%03d.jpg a.pdf

每个选项的含义:

  • sDEVICE={jpeg,pngalpha,png16m...} - 文件类型
  • -o - 输出文件(%stdout 到 stdout)
  • -dTextAlphaBits=4 - 字体抗锯齿。
  • -r300 - 300 dpi

To convert pdf to image files use following commands:

For PNG gs -sDEVICE=png16m -dTextAlphaBits=4 -r300 -o a.png a.pdf

For JPG gs -sDEVICE=jpeg -dTextAlphaBits=4 -r300 -o a.jpg a.pdf

If you have multiple pages add to name %03d gs -o a%03d.jpg a.pdf

What each option means:

  • sDEVICE={jpeg,pngalpha,png16m...} - filetype
  • -o - output file (%stdout to stdout)
  • -dTextAlphaBits=4 - font antialiasing.
  • -r300 - 300 dpi
柒七 2024-07-22 20:10:34

还可以使用 poppler-utils 包中包含的命令行实用程序:

sudo apt-get install poppler-utils
pdftoppm --help
pdftocairo --help

示例:

pdftocairo -png mypage.pdf mypage.png

One can also use the command line utilities included in poppler-utils package:

sudo apt-get install poppler-utils
pdftoppm --help
pdftocairo --help

Example:

pdftocairo -png mypage.pdf mypage.png
嘿哥们儿 2024-07-22 20:10:34

无法获得可接受的工作答案。 然后发现实际上解决方案要简单得多,因为 Ghostscript 不仅原生支持 PNG,甚至 多个不同的“编码”

  • png256
  • png16
  • pnggray
  • pngmono
  • ...

适用于的shell命令我是:

gs -dNOPAUSE -q -sDEVICE=pnggray -r500 -dBATCH -dFirstPage=2 -dLastPage=2 -sOutputFile=test.png test.pdf

它将使用 pnggray 编码和 500 DPI 将 test.pdf 的第 2 页保存到 test.png。

Couldn't get the accepted answer to work. Then found out that actually the solution is much simpler anyway as Ghostscript not just natively supports PNG but even multiple different "encodings":

  • png256
  • png16
  • pnggray
  • pngmono
  • ...

The shell command that works for me is:

gs -dNOPAUSE -q -sDEVICE=pnggray -r500 -dBATCH -dFirstPage=2 -dLastPage=2 -sOutputFile=test.png test.pdf

It will save page 2 of test.pdf to test.png using the pnggray encoding and 500 DPI.

由于此页面还列出了替代工具,我将提到 xpdf 它具有命令行为 Linux/Windows/Mac 编译的工具。 支持透明度。 可免费用于商业用途 - 与 Ghostscript 不同,Ghostscript 的定价确实令人震惊

在对大型 PDF 文件进行的测试中,它比 Ghostscript 快 7.5%。

(它还有 PDF 到文本和 HTML 转换器)

As this page also lists alternative tools I'll mention xpdf which has command line tools ready compiled for Linux/Windows/Mac. Supports transparency. Is free for commercial use - opposed to Ghostscript which has truly outrageous pricing.

In a test on a huge PDF file it was 7.5% faster than Ghostscript.

(It also has PDF to text and HTML converters)

っ左 2024-07-22 20:10:34

我会添加我的解决方案,即使他的线程已经过时了。 也许这无论如何都会对某人有所帮助。

首先,我需要生成 PDF。 我使用 XeLaTeX 来实现:

xelatex test.tex

现在,ImageMagickGraphicMagic 都从左到右解析参数右,因此最左边的参数将首先执行。 我最终使用这个序列来实现最佳处理:

gm convert -trim -transparent white -background transparent -density 1200x1200 -resize 25% test.pdf test.png

它在透明背景上提供了漂亮的图形,并根据页面上的实际内容进行了修剪。 -密度-resize 参数提供更好的粒度,并提高整体分辨率。

我建议检查是否可以为您降低密度。 它将减少转换时间。

I'll add my solution, even thought his thread is old. Maybe this will help someone anyway.

First, I need to generate the PDF. I use XeLaTeX for that:

xelatex test.tex

Now, ImageMagick and GraphicMagic both parse parameters from left to right, so the leftmost parameter, will be executed first. I ended up using this sequence for optimal processing:

gm convert -trim -transparent white -background transparent -density 1200x1200 -resize 25% test.pdf test.png

It gives nice graphics on transparent background, trimmed to what is actually on the page. The -density and -resize parameters, give a better granularity, and increase overall resolution.

I suggest checking if the density can be decreased for you. It'll cut down converting time.

幽梦紫曦~ 2024-07-22 20:10:34

对于 ImageMagick 给出的颜色不准确的 PDF,我发现 GraphicsMagick 做得更好:

$ gm convert -quality 100 -thumbnail x300 -flatten journal.pdf\[0\] cover.jpg

For a PDF that ImageMagick was giving inaccurate colors I found that GraphicsMagick did a better job:

$ gm convert -quality 100 -thumbnail x300 -flatten journal.pdf\[0\] cover.jpg
坐在坟头思考人生 2024-07-22 20:10:34

尝试提取单个页面。

$页 = 4

gs -sDEVICE=pngalpha -dFirstPage="$page" -dLastPage="$page" -o thumb.png -r144 input.pdf

Try to extract a single page.

$page = 4

gs -sDEVICE=pngalpha -dFirstPage="$page" -dLastPage="$page" -o thumb.png -r144 input.pdf
江南月 2024-07-22 20:10:34

我的解决方案更简单、更直接。 至少它在我的电脑上是这样工作的(具有以下规格):

me@home: my.folder$ uname -a
Linux home 3.2.0-54-generic-pae #82-Ubuntu SMP Tue Sep 10 20:29:22 UTC 2013 i686 i686 i386 GNU/Linux

因此

me@home: my.folder$ convert --version
Version: ImageMagick 6.6.9-7 2012-08-17 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC
Features: OpenMP

,这是我在 file.pdf 上运行的内容:

me@home: my.folder$ convert -density 300 -quality 100 file.pdf file.png

My solution is much simpler and more direct. At least it works that way on my PC (with the following specs):

me@home: my.folder$ uname -a
Linux home 3.2.0-54-generic-pae #82-Ubuntu SMP Tue Sep 10 20:29:22 UTC 2013 i686 i686 i386 GNU/Linux

with

me@home: my.folder$ convert --version
Version: ImageMagick 6.6.9-7 2012-08-17 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC
Features: OpenMP

So, here's what I run on my file.pdf:

me@home: my.folder$ convert -density 300 -quality 100 file.pdf file.png
顾挽 2024-07-22 20:10:34

您可以使用 ImageMagick,而无需使用其他工具分离 PDF 的首页。 就做

convert -density 288 cover.pdf[0] -resize 25% cover.png

这里我将标称密度增加 400% (72*4=288),然后调整大小 1/4 (25%)。 这为生成的 png 提供了更好的质量。

但是,如果 PDF 是 CMYK,则 PNG 不支持。 它需要转换为 sRGB,特别是如果它具有透明度,因为 Ghostscript 无法处理带有 alpha 的 CMYK。

convert -density 288 -colorspace sRGB -resize 25% cover.pdf[0] cover.png

You can use ImageMagick without separating the first page of the PDF with other tools. Just do

convert -density 288 cover.pdf[0] -resize 25% cover.png

Here I increase the nominal density by 400% (72*4=288) and then resize by 1/4 (25%). This gives a much better quality for the resulting png.

However, if the PDF is CMYK, PNG does not support that. It would need to be converted to sRGB, especially if it has transparency, since Ghostscript cannot handle CMYK with alpha.

convert -density 288 -colorspace sRGB -resize 25% cover.pdf[0] cover.png
¢蛋碎的人ぎ生 2024-07-22 20:10:34

我研究了给出的答案,然后将它们与我的扫描仪进行了比较,该扫描仪可以扫描为 PDF 或可以扫描为图像(通常是 JPEG)。 我发现以下内容:

  • 通常扫描仪在 300 DPI 下工作,有时在 600 DPI 下更高或在 150 DPI 下更低
  • 扫描的图像通常是完整的 24 位 RGB 颜色(每条带 8 位),并且通常压缩为 JPEG
  • PNG,但是,通常是用于数字绘图,通常是带有调色板的 8 位
  • PDF 通常是多页,而 PNG 和 JPEG 通常是单页

当从 PDF 转换为 PNG 时,我们必须问自己是否要使用默认的 300 DPI 还是我们是否想要以更高分辨率 600 DPI 或更低分辨率 150 DPI 重新采样图像。 我们还必须问自己 PDF 是否包含照片,因此我们需要 24 位图像,即 png16m。 或者,如果 PDF 仅包含数字文档,主要是黑白文本,但可能包含有限数量的颜色,则 8 位图像格式就足够了,即 png256。 我们还需要问自己是否想要访问多个页面或满足于一个页面。

对于答案的其余部分,我将假设 300 DPI 和不包含照片的数字文档,即 8 位格式(或 256 色格式)。

对于单页提取,我确定参数需要为 PDFPNGPAGENO

#!/bin/bash
# Usage: pdf2png.sh input.pdf output.png pageno
PDF=$1
PNG=$2
PAGENO=$3
FORMAT=png256 # png16m png16 pngmono
DPI=300 # 600 150
cmd=(gs)
cmd+=(-dNOPAUSE)
cmd+=(-q)
cmd+=(-sDEVICE=${FORMAT})
cmd+=(-r${DPI})
cmd+=(-dBATCH)
cmd+=(-dFirstPage=${PAGENO})
cmd+=(-dLastPage=${PAGENO})
cmd+=(-sOutputFile=${PNG})
cmd+=(${PDF})
${cmd[@]}

对于多页提取,我确定参数需要是 PDFDIR

#!/bin/bash
# Usage: pdf2pngs.sh input.pdf outputdir
PDF=$1
DIR=$2
FORMAT=png256 # png16m png16 pngmono
DPI=300 # 600 150
mkdir -p ${DIR}
cmd=(gs)
cmd+=(-dNOPAUSE)
cmd+=(-q)
cmd+=(-sDEVICE=${FORMAT})
cmd+=(-r${DPI})
cmd+=(-dBATCH)
cmd+=(-sOutputFile=${DIR}/'p%d.png')
cmd+=(${PDF})
${cmd[@]}

要将页面重新合并为 PNG,我们可以使用 ImageMagick convert,如下所示:

#!/bin/bash
# pngs2pdf.sh dir output.pdf
DIR=$1
PDF=$2
convert ${DIR}/*.png ${PDF}

I studied the answers presented and then compared them to my scanner which can scan to PDF or can scan to image (typically JPEG). I found the following:

  • Typically scanners work at 300 DPI, sometimes higher at 600 DPI or lower at 150 DPI
  • The scanned images are typically full 24 bit RGB color (8 bits per band) and are typically compressed as JPEG
  • PNGs, however, are typically used for digital drawings and are typically 8-bit with a palette
  • PDFs are typically multi-page, whereas PNG and JPEG are typically a single page

When converting from PDF to PNG we have to ask ourselves whether we want to use the default 300 DPI or whether we want to resample the image at a higher resolution 600 DPI or lower resolution 150 DPI. We also have to ask ourselves if the PDF contains photos and therefore we need 24-bit images, i.e. png16m. Alternatively, if the PDF just contains digital documents, predominantly black and white text but may contain a limited number of colors, then, an 8-bit image format is sufficient, i.e. png256. We also need to ask ourselves whether we want to have access to multiple pages or are content with one page.

For the rest of the answer, I will assume 300 DPI and digital documents that do not contain photos, i.e. 8-bit format (or 256-color format).

For a single page extraction, I determine the parameters need to be PDF, PNG, and PAGENO:

#!/bin/bash
# Usage: pdf2png.sh input.pdf output.png pageno
PDF=$1
PNG=$2
PAGENO=$3
FORMAT=png256 # png16m png16 pngmono
DPI=300 # 600 150
cmd=(gs)
cmd+=(-dNOPAUSE)
cmd+=(-q)
cmd+=(-sDEVICE=${FORMAT})
cmd+=(-r${DPI})
cmd+=(-dBATCH)
cmd+=(-dFirstPage=${PAGENO})
cmd+=(-dLastPage=${PAGENO})
cmd+=(-sOutputFile=${PNG})
cmd+=(${PDF})
${cmd[@]}

For a multiple-page extraction, I determine the parameters need to be PDF and DIR:

#!/bin/bash
# Usage: pdf2pngs.sh input.pdf outputdir
PDF=$1
DIR=$2
FORMAT=png256 # png16m png16 pngmono
DPI=300 # 600 150
mkdir -p ${DIR}
cmd=(gs)
cmd+=(-dNOPAUSE)
cmd+=(-q)
cmd+=(-sDEVICE=${FORMAT})
cmd+=(-r${DPI})
cmd+=(-dBATCH)
cmd+=(-sOutputFile=${DIR}/'p%d.png')
cmd+=(${PDF})
${cmd[@]}

To join the pages back together to PNG, we can make use of ImageMagick convert as follows:

#!/bin/bash
# pngs2pdf.sh dir output.pdf
DIR=$1
PDF=$2
convert ${DIR}/*.png ${PDF}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文