如何使用ImageMagick将SVG转换为PNG?

583

我有一个被定义为16x16大小的SVG文件。当我使用ImageMagick的convert程序将其转换为PNG格式时,我得到了一个太小的16x16像素PNG图片:

convert test.svg test.png

我需要指定输出PNG的像素大小。 -size 参数似乎被忽略了,-scale 参数会在将PNG转换为PNG后进行缩放。-density 参数是目前为止我得到的最佳结果:

convert -density 1200 test.svg test.png

但我不满意,因为我想以像素为单位指定输出大小,而不需要进行数学计算来计算密度值。所以我想要做这样的事情:

convert -setTheOutputSizeOfThePng 1024x1024 test.svg test.png

那么我需要在这里使用什么神奇的参数呢?


7
好的,请问您需要翻译什么内容呢? - Dejan Marjanović
1
http://superuser.com/questions/516095/bake-an-svg-image-into-a-png-at-a-given-resolution - Dave Jarvis
2
ImageMagick-6.9.0-Q16。 convert -resize 1024x1024 foo.svg foo.png 可以正常工作。 - Jichao
13
-resize 命令会简单地拉伸转换后的图像,结果质量较差。 - Elist
13
使用ImageMagick 7.0.7-0 Q16(Windows Chocolatey库中的当前版本),convert -size 1024x1024 test.svg test.png可以正常工作。只需确保在输入文件名之前出现-size参数,否则会将16x16的图片放大以产生模糊效果。 - Futal
显示剩余3条评论
20个回答

711
我在这个情况下无法从ImageMagick获得好的结果,但Inkscape在Linux和Windows上可以很好地缩放SVG。
# Inkscape v1.0+
inkscape -w 1024 -h 1024 input.svg -o output.png

# Inkscape older than v1.0
inkscape -z -w 1024 -h 1024 input.svg -e output.png

请注意,您可以省略宽度/高度参数之一,让另一个参数根据输入图像的尺寸自动缩放。
以下是使用此命令将16x16 SVG缩放为200x200 PNG的结果:

enter image description here

enter image description here


21
就ImageMagick而言,+1。似乎SVG引擎存在问题,在大多数情况下我无法得到准确的结果。相比之下,Inkscape运行得非常好。 - Glutanimate
20
我认为Inkscape是继Linux之后最令人印象深刻的开源软件范例。谢谢你的建议! - kim3er
10
在OSX上也表现良好。 - Jonas Granvik
17
在OSX上,如果已经安装了X11版的Inkscape,可以使用以下命令:/Applications/Inkscape.app/Contents/Resources/bin/inkscape -z -e test.png -w 1024 -h 1024 test.svg来将test.svg文件转换为1024x1024分辨率的test.png文件。 - chmullig
17
要使用ImageMagick保持背景透明,可以使用命令行选项“-background none”。 - John
显示剩余27条评论

194

试试svgexport

svgexport input.svg output.png 64x
svgexport input.svg output.png 1024:1024

svgexport是一个简单的跨平台命令行工具,我创建它是为了将svg文件导出为jpg和png格式。更多选项请参见这里。要安装svgexport,请先安装npm,然后运行以下命令:

npm install svgexport -g

编辑:如果您发现了该库的问题,请在 GitHub 上提交,谢谢!


7
SVG导出对我非常有效。输出与浏览器呈现更加匹配,比ImageMagick好很多。 - t9mike
1
这对我也很有效。与在GUI工具中手动操作相比,这是一个真正的时间节省者。在Mac上找到一个价格便宜且能够良好处理SVG的GUI应用程序相当困难。 - Erik Engheim
4
功能出色,但生成的图片非常大。使用optipng工具,我成功将文本logo从3兆字节压缩到了约20千字节。 - miek
@AliShakiba,您能指导我如何在Windows上使用它吗?如果您能告诉我如何在我的Visual Studio 2015应用程序中使用您的代码,那就更好了。 - ubaabd
4
evgexport根据大小创建巨大的PNG文件。建议使用svg2png进行导出,它也使用PhantomJS,但创建的图像要小得多。 - Aaron_H
显示剩余9条评论

146

这不是完美的,但它能够完成工作。

convert -density 1200 -resize 200x200 source.svg target.png

基本上,它会将DPI增加到足够高的程度(只需要使用经过教育的/安全的猜测),以便以足够的质量进行调整大小。我试图找到一个合适的解决方案,但过了一段时间后,我决定这对我当前的需求已经足够好了。

注意:使用200x200!强制给定分辨率


7
我的情况下,不透明度和阴影丢失了。 - jiyinyiyong
2
我没有复杂的SVG,所以这对我起作用了。-resize 200%不起作用,我必须指定像素大小。 - jozxyqk
30
要使用ImageMagick保持背景透明,请使用“-background none”命令行选项。要保持图像比例,您还可以指定其中一个维度,例如“-resize 200”表示宽度或“-resize x200”表示高度。有关详尽的ImageMagick几何选项,请参见:http://www.imagemagick.org/script/command-line-processing.php#geometry - John
对我也不起作用。结果都模糊不清。 - mbonnin
1
批处理版本为for file in ./*.svg; do convert -density 1200 -background none -resize 200x200 $file `basename $file .svg`.png; done - polkovnikov.ph
显示剩余3条评论

87

Inkscape似乎无法处理SVG单位不是px(例如cm)的情况。我得到了一个空白图像。也许可以通过调整dpi来修复它,但这太麻烦了。

Svgexport是一个Node.js程序,因此通常没有用处。

Imagemagick的convert可以正常工作:

 convert -background none -size 1024x1024 infile.svg outfile.png

如果您使用-resize,图像会变得模糊,并且文件大小更大。

BEST

rsvg-convert -w 1024 -h 1024 infile.svg -o outfile.png

它是最快的,依赖最少,输出文件大约比convert小30%。 安装librsvg2-bin以获取它:

sudo apt install -y librsvg2-bin

似乎没有man手册,但您可以输入:

rsvg-convert --help

需要一些帮助。简单就好。


4
这很容易成为最佳答案(我不知道为什么有二十个不同的答案都给出了同样的imagemagick响应);它保留了颜色和阴影,没有损坏任何东西。然而,为了匹配imagemagick的调整大小行为(特别是,WxH表示将图像缩放以适合该尺寸的框中,并保持纵横比),应该使用-rsvg参数。 - Mahmoud Al-Qudsi
7
FYI,当前的安装命令是brew install librsvg,转换命令是rsvg-convert - waldyrious
4
我发现使用librsvg(在Arch中称为rsvg-convert)转换复杂的SVG到PNG格式时,效果最佳且最一致。然后可以使用optipng进一步压缩输出文件大小。 - maktel
3
在Ubuntu中:sudo apt install librsvg2-bin; rsvg-convert input.svg -o output.png 表示安装librsvg2-bin软件包,并将输入的SVG文件转换为PNG格式的输出文件。 - MestreLion
1
在对将SVG转换为PNG的各种方式进行了一些性能测试后,我发现rsvg-convert是迄今为止最快的(至少比使用Chromium的Puppeteer,使用Chromium的Playwright,ImageMagick,Inkscape和SVG.NET都要快得多)。 - George Helyar
显示剩余5条评论

60

如果您在MacOS X上使用Imagemagick的convert时遇到问题,可以尝试使用RSVG库重新安装它。 使用HomeBrew:

brew remove imagemagick
brew install imagemagick --with-librsvg

验证它是否正确委派:

$ convert -version
Version: ImageMagick 6.8.9-8 Q16 x86_64 2014-12-17 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
Features: DPC Modules
Delegates: bzlib cairo fontconfig freetype jng jpeg lcms ltdl lzma png rsvg tiff xml zlib

它应该显示rsvg


1
对我来说完美地工作了 - 默认的 convert 确实将 svg 转换为 png,但结果很糟糕;重新安装后,它们变得完美。此外,转换速度显著提高。 - ssc
1
这在我的Mac OSX上运行良好。我没有发现新的转换速度更快,但准确性更高得多。我强烈建议所有Mac OSX用户尝试一下。 - ABCD
1
这应该是被接受的答案,好吧。谢谢,运行得很好,否则我永远不会知道要采取这些步骤。 - sdailey
21
在Mojave上,我收到了“无效选项:--with-librsvg”的错误提示。 - zaitsman
4
也许已经太晚了,但是选项参数已经改变了,请尝试使用 --with-rsvg。我认为需要安装 librsvg2-bin 包。 请参阅 https://gist.github.com/maxivak/1476f7e979879da9f75371a86d5627b5 - NickGnd
显示剩余3条评论

23

在跟随 Jose Alban的回答 中的步骤后,我能够使用以下命令使ImageMagick正常工作:

convert -density 1536 -background none -resize 100x100 input.svg output-100.png

数字1536来自于密度的粗略估计,有关更多信息,请参见此答案


请使用"-size"代替,显然在某些IM版本中,使用resize会使图像变得模糊。 - João Pimentel Ferreira

20
在ImageMagick中,如果使用Inkscape或RSVG与ImageMagick一起使用,可以获得更好的SVG渲染效果,而不是使用ImageMagick自己内部的MSVG/XML渲染器。 RSVG是一个需要与ImageMagick一起安装的委托。如果系统上安装了Inkscape,则ImageMagick将自动使用它。下面我在ImageMagick中使用Inkscape。
没有“神奇”的参数可以做到你想要的效果。
但是,可以非常简单地计算出需要渲染输出所需的精确密度。
这是一个小的50x50按钮,当以默认密度96呈现时:
convert button.svg button1.png


enter image description here

假设我们希望输出为500。默认密度下输入为50,密度为96(旧版本的Inkscape可能使用92)。因此,您可以根据尺寸和密度的比例计算所需的密度。
512/50 = X/96
X = 96*512/50 = 983


convert -density 983 button.svg button2.png


enter image description here

在ImageMagick 7中,您可以按如下方式进行内联计算:
magick -density "%[fx:96*512/50]" button.svg button3.png

or

in_size=50
in_density=96
out_size=512

magick -density "%[fx:$in_density*$out_size/$in_size]" button.svg button3.png

2
+1 对于神奇的 fx 表达式,它避免了单独的命令或使用计算器。另外,如果你运行 identify -format "%x x %y (%w x %h) file.svg,你也会在输出中得到默认密度的宽度和高度(这是公式中需要的 $in_size)! - Till Kuhn
你甚至可以在一行代码中完成它。 - Torsten B
谢谢!它像魔法一样运行!如果你添加选项-background none,你也会得到一个带有透明背景的.png文件! - Mattia Ducci

18

为了重新缩放图像,应使用选项-density。据我所知,标准密度为72,将大小映射为1:1。如果您希望输出的PNG比原始SVG大两倍,请将密度设置为72 * 2 = 144:

convert -density 144 source.svg target.png

请注意,转换选项必须位于输入文件之前。即convert source.svg -density 144 target.png不会重新调整图像大小。 - Skippy le Grand Gourou
实际上,标准密度似乎是90。因此,应该使用convert -density 180 source.svg target.png - adius

17

在 macOS 上使用 Homebrew,直接使用 librsvg 的效果很好。

brew install librsvg
rsvg-convert test.svg -o test.png

通过rsvg-convert --help可以获得很多选项。


11

对于简单的SVG转PNG转换,我发现cairosvg(https://cairosvg.org/)比ImageMagick性能更好。以下是安装和在目录中运行所有SVG文件的步骤。

pip3 install cairosvg
在包含你的 .svg 文件的目录中打开一个 Python shell 并运行:
import os
import cairosvg

for file in os.listdir('.'):
    name = file.split('.svg')[0]
    cairosvg.svg2png(url=name+'.svg',write_to=name+'.png') 

这也可以确保您不会覆盖原始的 .svg 文件,但是将保持相同的名称。然后,您可以使用以下命令将所有 .png 文件移动到另一个目录中:

$ mv *.png [new directory]

在Windows 10上崩溃了: import cairocffi as cairo File "c:\program files (x86)\python35-32\lib\site-packages\cairocffi_init.py", line 39, in <module> cairo = dlopen(ffi, 'cairo', 'cairo-2', 'cairo-gobject-2', 'cairo.so.2') File "c:\program files (x86)\python35-32\lib\site-packages\cairocffi_init.py", line 36, in dlopen raise OSError("dlopen() failed to load a library: %s" % ' / '.join(names)) OSError: dlopen() 无法加载库:cairo / cairo-2 / cairo-gobject-2 / cairo.so.2 - Pete Lomax
1
很好,cairosvg 在 Ubuntu-19.04 上为我完成了工作。 - fhgd
我只是想写:多么出色的解决方案!第一批PNG看起来很棒,但其他的不行。相反,我必须写:哪种解决方案提供最佳质量完全取决于SVG。 - Regis May
cairosvg 在 Ubuntu 20.04 实例(WSL 和 Gcloud 免费版 VM)上为我工作。从基础镜像开始,我必须运行 sudo apt install python3-pip 命令,然后运行上面的 pip3 install cairosvg 命令。从那里,我就能够使用 ~/.local/bin/cairosvg 中的命令行可执行文件。 - Marc

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