关于imagemagick:如何使用Image Magick将SVG转换为PNG?

How to convert a SVG to a PNG with Image Magick?

我有一个SVG文件,它的定义大小为16x16。当我使用image magick的convert程序将其转换为PNG时,我会得到一个16x16像素的PNG,它太小了:

1
convert test.svg test.png

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

1
convert -density 1200 test.svg test.png

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

1
convert -setTheOutputSizeOfThePng 1024x1024 test.svg test.png

那么我在这里要用到的魔法参数是什么呢?


在本例中,我无法从ImageMagick获得良好的效果,但Inkscape在Linux和Windows上做得很好:

1
inkscape -z -e test.png -w 1024 -h 1024 test.svg

下面是使用此命令将16x16 SVG缩放为200x200 PNG的结果:

enter image description here

enter image description here

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

1
Inkscape 0.48.3.1 r9886 (Mar 29 2012)

在Windows7上,它是:

1
Inkscape 0.48.4 r9939 (Dec 17 2012)


尝试SvgEx销:

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

svgexport是一个简单的跨平台命令行工具,我为将svg文件导出到JPG和PNG而制作的,有关更多选项,请参阅此处。要安装svgexport,请安装npm,然后运行:

1
npm install svgexport -g

编辑:如果您发现图书馆有问题,请在Github上提交,谢谢!


这不是完美的,但它确实起到了作用。

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

基本上,它增加了足够高的dpi(只是使用一个受过教育的/安全的猜测),调整大小是以足够的质量完成的。我试图找到一个合适的解决办法,但过了一段时间后,我觉得这已经足够满足我目前的需要了。

Note: Use 200x200! to force the given resolution


如果您在MacOSX上,并且ImageMagick的转换有问题,您可以尝试用rsvg lib重新安装它。使用自制软件:

1
2
brew remove imagemagick
brew install imagemagick --with-librsvg

验证其授权是否正确:

1
2
3
4
5
$ 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


当SVG单元不是px时(例如cm),Inkscape似乎不起作用。我得到一张空白的图片。也许,可以通过旋转DPI来修复,但这太麻烦了。

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

ImageMagick的Convert工作正常:

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

如果使用-resize,则图像模糊,文件大得多。

最好的

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

它速度最快,依赖性最小,输出比转换小30%。安装librsvg2-bin获取。似乎没有主页,但您可以键入:

1
~$ rsvg --help

去寻求帮助。简单就是好。


按照Jose Alban的回答中的步骤,我可以使用以下命令让ImageMagick正常工作:

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

1536来自于对密度的大致估计,更多信息请参见此答案。


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

1
convert -density 144 source.svg target.png


为什么不尝试使用inkscape命令行,这是我的BAT文件,用于将此目录中的所有SVG转换为png:

FOR %%x IN (*.svg) DO C:\Ink\App\Inkscape\inkscape.exe %%x -z --export-dpi=500 --export-area-drawing --export-png="%%~nx.png"


我来写这篇文章——但是我只想成批快速地进行转换,而不使用任何参数(由于有几个文件大小不同)。

1
rsvg drawing.svg drawing.png

对我来说,要求可能比原作者要简单一些。(希望在MS PowerPoint中使用SVG,但不允许)


有一件事让我有点恼火,那就是在输入文件名后面设置-density。那不管用。将它移动到convert中的第一个选项(在其他任何操作之前)使它工作(对于我、ymmv等)。


我通过更改标记的widthheight属性来匹配我的预期输出大小,然后使用imagemagick转换它来解决这个问题。很有魅力。

下面是我的python代码,一个返回JPG文件内容的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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


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

1
pip3 install cairosvg

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

1
2
3
4
5
import os

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

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

1
$ mv *.png [new directory]


@808Sound的最佳答案不适合我。我想调整大小Kenney.nl UI Pack

并且得到Kenney UI Pack messed up

所以我打开了Inkscape,然后去了FileExport as PNG file,弹出了一个GUI框,允许我设置所需的确切尺寸。

Ubuntu 16.04 Linux上的版本:Inkscape 0.91 (September 2016)

(顺便说一下,这张图片来自肯尼荷兰的资产包)