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


388

我有一个已定义大小为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

那么我在这里必须使用的魔术参数是什么?


6
例如-size 1024x1024工作正常,您的imagemagick版本是什么?
Dejan Marjanovic


2
ImageMagick-6.9.0-Q16。convert -resize 1024x1024 foo.svg foo.png工作正常。
吉超2015年

11
@Jichao -resize只是拉伸转换后的图像,结果质量很差。
Elist

5
convert -size 1024x1024 test.svg test.png与ImageMagick 7.0.7-0 Q16(Windows版Chocolatey回购中的当前版本)配合使用时效果很好。只要确保它-size出现在输入文件名之前,否则16x16图片将被放大以产生模糊的结果。
致命的

Answers:


502

在这种情况下,我无法从ImageMagick获得好的结果,但是Inkscape在Linux和Windows上做得很好:

inkscape -z -w 1024 -h 1024 input.svg -e output.png

编辑(2020年5月):Inkscape 1.0用户,请注意命令行参数已更改:

inkscape -w 1024 -h 1024 input.svg --export-filename output.png

这是使用此命令将16x16 SVG缩放到200x200 PNG的结果:

在此处输入图片说明

在此处输入图片说明

仅供参考,我的Inkscape版本(在Ubuntu 12.04上)为:

Inkscape 0.48.3.1 r9886 (Mar 29 2012)

在Windows 7上为:

Inkscape 0.48.4 r9939 (Dec 17 2012)

15
就imagemagick而言+1。SVG引擎似乎有问题。在大多数情况下,我无法获得准确的结果。OTOH的Inkscape工作正常。
谷氨酰胺

13
我认为Inkscape是继Linux本身之后OSS最令人印象深刻的例子。谢谢你的提示!
kim3er

8
在OSX上也能很好地工作。
Jonas Granvik

12
在OSX上(为X11安装了Inkscape的情况下),它可以通过以下方式为我工作:/Applications/Inkscape.app/Contents/Resources/bin/inkscape -z -e test.png -w 1024 -h 1024 test.svg
chmullig 2014年

11
@Rörd要使ImageMagick保持背景透明,请使用-background none命令行选项。
约翰

142

尝试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上提交,谢谢!


4
svgexport对我来说很棒。输出与浏览器渲染的匹配比ImageMagick更紧密。
t9mike 2015年

5
svgexport质量确实很高。现在,它已成为我最喜欢的工具,谢谢shakiba!:)
Alessio Periloso,2015年

1
这对我也很好。与在GUI工具中手动完成相比,实时保护程序更容易。无论如何,要在Mac上找到价格便宜的GUI应用程序非常困难,因为它可以很好地处理SVG
Erik Engheim 2015年

4
效果很好,但产生了巨大的图像。使用optipng,我可以将文本徽标从3 MB压缩到〜20kB。
miek

2
evgexport根据大小创建巨大的png文件。推荐svg2png,它也使用PhantomJS进行导出,但是创建的图像要小得多。
Aaron_H

112

这不是完美的,但确实可以做到。

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

基本上,它将DPI增加到足够高的程度(只需使用有根据的/安全的猜测即可),从而可以以足够的质量调整大小。我试图为此找到合适的解决方案,但过了一会儿,这已经足够满足我当前的需求。

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


4
在我的情况下,不透明度和阴影消失了。
jiyinyiyong 2014年

2
我没有复杂的svg,所以这对我有用。-resize 200%无法正常工作,我必须以像素为单位指定大小。
jozxyqk 2014年

18
@jiyinyiyong要使用ImageMagick保持背景透明,请使用-background none命令行选项。为了保持图像比例,还可以仅指定一个尺寸,例如-resize 200宽度或-resize x200高度。有关详尽的ImageMagick几何选项,请参见:imagemagick.org/script/command-line-processing.php#geometry
约翰

也不适合我 结果是所有的模糊。
mbonnin

(这适用于linux,可能适用于Windows)如果在IM上启用-verbose,则IM本身似乎使用inkscape创建了中间eps文件。因此,我建议按照@ 808sound的建议直接使用inkscape
Northern-bradley

55

如果您使用的是MacOS X,并且Imagemagick的convert出现问题,则可以尝试使用RSVG lib重新安装它。使用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


没为我工作。具体来说,我跑convert ic_comment_48px.svg -size 30x30 ic_comment_30px.png了,输出的图像是48 x48。按照您的说明,确保imagemagick委托给rsvg。
Shane Creighton-Young

1
对我来说非常完美-默认值convert确实将svg转换为png,但结果无望。重新安装后,它们是完美的。而且,转换速度明显更快。
ssc

1
这使我在Mac OSX上工作。我找不到新的转换更快,但更准确的。我强烈建议所有Mac OSX用户尝试一下。
HelloWorld

1
哦,这应该是公认的答案。谢谢,像魅力一样工作,否则我从来不知道会采取这些步骤
sdailey

8
在莫哈韦invalid option: --with-librsvg
沙漠上,

39

不使用svg单位px(例如cm)时,Inkscape似乎不起作用。我有空白图像。也许可以通过旋转dpi来解决它,但这太麻烦了。

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

Imagemagick的convert可以在以下情况下正常工作:

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

如果使用-resize,则图像模糊并且文件很大。

最好

~$ rsvg  -w 1024 -h 1024 infile.svg  outfile.png

它是最快的,具有最少的依赖项,并且输出比convert小约30%。安装librsvg2-bin以获取它。似乎没有手册页,但您可以输入:

~$ rsvg --help

得到一些帮助。简单就是好。


2
这很容易是最好的答案(我不知道为什么二十个不同的答案会给出相同的imagemagick响应);它保留了颜色和阴影,没有任何变形。但是,为了匹配imagemagick的调整大小行为(特别是WxH表示将图像缩放为适合该大小的框,并保留宽高比),该-a参数应与rsvg一起使用。
马哈茂德·古德西

1
这弄乱了我的图像,各种奇怪的伪像。inkscape做得更好。
优雅的骰子

1
被警告,brew install rsvg在OSX上安装一个亿的事情- GDK,OpenSSL的,Python等
Timmmm

4
仅供参考,当前安装命令为brew install librsvg,转换命令为rsvg-convert
waldyrious

rsvg-convert当将复杂的svgs转换为png时,我发现librsvg(或在Arch的情况下)给出最佳和最一致的结果。跟进optipng以减小输出文件的大小。
maktel

18

在遵循Jose Alban的答案中的步骤之后,我可以使用以下命令使ImageMagick正常工作:

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

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


15

为了重新缩放图像,-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 2015年

实际上,标准密度似乎是90。所以应该是convert -density 180 source.svg target.png
adius

7

您为什么不尝试inkscape命令行,这是我的bat文件,用于将该目录中的所有svg转换为png:

FOR %% x IN(* .svg)执行C:\ Ink \ App \ Inkscape \ inkscape.exe %% x -z --export-dpi = 500 --export-area-drawing --export-png =“% %〜nx.png”


4

我来这篇文章-但我只想按批处理快速进行转换,而无需使用任何参数(由于几个具有不同大小的文件)。

rsvg drawing.svg drawing.png

对我来说,要求可能比原始作者要容易一些。(想在MS PowerPoint中使用SVG,但这是不允许的)


1
作为参考,在macOS上安装了brew install librsvg,转换命令为rsvg-convert
waldyrious

在Ubutni中,它也是rsvg-convert,包也是librsvg2-bin,输出需要-o drawing.png
teknopaul,

4

在ImageMagick中,如果将Inkscape或RSVG与ImageMagick一起使用,则将获得比其内部内部MSVG / XML更好的SVG渲染。RSVG是需要与ImageMagick一起安装的委托。如果系统上安装了Inkscape,ImageMagick将自动使用它。我在下面的ImageMagick中使用Inkscape。

没有任何“魔术”参数可以满足您的需求。

但是,可以非常简单地计算渲染输出所需的确切密度。

当以默认密度96渲染时,这是一个50x50的小按钮:

convert button.svg button1.png


在此处输入图片说明

假设我们希望输出为500。输入为50,默认密度为96(较旧版本的Inkscape可能使用92)。因此,您可以与尺寸和密度之比成比例地计算所需的密度。

512/50 = X/96
X = 96*512/50 = 983


convert -density 983 button.svg button2.png


在此处输入图片说明

在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

magick DSL中的方程式非常有用!
cyrf

2

令我-density困扰的一件事是在输入文件名之后设置。那没用。将其移至convert中的第一个选项(之前没有执行其他任何操作)使它可以工作(对我来说,YMMV等)。


2

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

pip3 install cairosvg

在包含.svg文件的目录中打开python shell并运行:

import os

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上为我崩溃:将cairocffi作为cairo文件“ c:\ program files(x86)\ python35-32 \ lib \ site-packages \ cairocffi_ init_ .py”,第39行,在<module> cairo = dlopen(ffi ,'cairo','cairo-2','cairo-gobject-2','cairo.so.2')文件“ c:\ program files(x86)\ python35-32 \ lib \ site-packages \ cairocffi_ init_ .py“,第36行,在dlopen中引发OSError(” dlopen()无法加载库:%s“%'/'.join(names))OSError:dlopen()无法加载库:cairo / cairo- 2 / cairo-gobject-2 / cairo.so.2
皮特·洛马克斯

很好,cairosvg在Ubuntu-19.04上为我完成了这项工作。
fhgd19年

2

没有librsvg,您可能会得到黑色的png / jpeg图像。我们必须使用imagemagick 安装librsvgconvertsvg文件。

的Ubuntu

 sudo apt-get install imagemagick librsvg
 convert -density 1200 test.svg test.png

苹果系统

 brew install imagemagick librsvg
 convert -density 1200 test.svg test.png

我没有安装此库,也没有黑色图像。
亚伦·弗兰克

1

我已经解决了此问题,方法是更改标签的widthheight属性<svg>以匹配我的预期输出大小,然后使用ImageMagick对其进行转换。奇迹般有效。

这是我的Python代码,该函数将返回JPG文件的内容:

import gzip, re, os
from ynlib.files import ReadFromFile, WriteToFile
from ynlib.system import Execute
from xml.dom.minidom import parse, parseString


def SVGToJPGInMemory(svgPath, newWidth, backgroundColor):

    tempPath = os.path.join(self.rootFolder, 'data')
    fileNameRoot = 'temp_' + str(image.getID())

    if svgPath.lower().endswith('svgz'):
        svg = gzip.open(svgPath, 'rb').read()
    else:
        svg = ReadFromFile(svgPath)

    xmldoc = parseString(svg)

    width = float(xmldoc.getElementsByTagName("svg")[0].attributes['width'].value.split('px')[0])
    height = float(xmldoc.getElementsByTagName("svg")[0].attributes['height'].value.split('px')[0])

    newHeight = int(newWidth / width * height) 

    xmldoc.getElementsByTagName("svg")[0].attributes['width'].value = '%spx' % newWidth
    xmldoc.getElementsByTagName("svg")[0].attributes['height'].value = '%spx' % newHeight

    WriteToFile(os.path.join(tempPath, fileNameRoot + '.svg'), xmldoc.toxml())
    Execute('convert -background "%s" %s %s' % (backgroundColor, os.path.join(tempPath, fileNameRoot + '.svg'), os.path.join(tempPath, fileNameRoot + '.jpg')))

    jpg = open(os.path.join(tempPath, fileNameRoot + '.jpg'), 'rb').read()

    os.remove(os.path.join(tempPath, fileNameRoot + '.jpg'))
    os.remove(os.path.join(tempPath, fileNameRoot + '.svg'))

    return jpg

2
您为什么要返回计算机生成的图像,例如jpeg :(?
Willi Mentzel,2016年

1

@ 808sound的最高答案对我不起作用。我想调整大小 Kenney.nl用户界面包

并得到了 Kenney UI Pack搞砸了

于是我又打开了Inkscape的,然后去了FileExport as PNG file和一个GUI框弹出,让我来设置,我需要精确的尺寸。

版本Ubuntu 16.04 LinuxInkscape 0.91 (September 2016)

(此图片来自Kenney.nl的资产包


1

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

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

可通过以下方式获得许多选择 rsvg-convert --help


0

在具有Inkscape 1.0的Linux上,从svg转换为png需要使用

inkscape -w 1024 -h 1024 input.svg --export-file output.png

inkscape -w 1024 -h 1024 input.svg --export-filename output.png
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.