如何使用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个回答

8
为什么不试试Inkscape命令行呢?以下是我的批处理文件,用于将此目录中的所有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"

8

这是对我有效且最容易运行的方法。

find . -type f -name "*.svg" -exec bash -c 'rsvg-convert -h 1000  $0 > $0.png' {} \;
rename 's/svg\.png/png/' *

这将循环遍历当前文件夹及其子文件夹中的所有文件,并查找 .svg 文件,并将其转换为具有透明背景的 png 格式。

请确保已安装 librsvg 和 rename util 工具。

brew install librsvg
brew install rename

6

使用ImageMagick 7,以目标高度/尺寸导出具有透明背景的图像:

magick -background none -size x1080 in.svg out.png

一行代码的批量转换器:

for i in *svg; do magick -background none -size x1080 "$i" "${i%svg}png"; done

我很惊讶这个答案的得分如此之低。其他一些方法会错误地绘制我的复杂SVG,但这个方法完美地解决了问题。 - Archr
我不得不使用 convert,但除此之外它完美地工作了(convert -background none -size x1080 in.svg out.png)。 - Michael Johansen

5

我来到了这篇帖子 - 但我只想批量快速进行转换,而且不使用任何参数(因为有几个文件大小不同)。

rsvg drawing.svg drawing.png

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


1
作为参考,在 macOS 上,可以通过 brew install librsvg 命令进行安装,并使用 rsvg-convert 命令进行转换。 - waldyrious
在Ubuntu中,也可以使用rsvg-convert,该软件包为librsvg2-bin,并且输出需要使用-o drawing.png。 - teknopaul

5

如果没有安装librsvg,可能会得到一张黑色的png/jpeg图片。我们需要安装librsvg来使用imagemagick转换svg文件。

Ubuntu

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

MacOS

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


我没有安装这个库,也没有遇到黑色图像的问题。 - Aaron Franke

4

有一件事情刚刚让我吃了亏,那就是在输入文件名之后设置 -density。这样做是行不通的。将其移动到 convert 的第一个选项(在任何其他选项之前)可以使其正常工作(对我而言如此,可能因人而异等等)。


2
在Linux上使用Inkscape 1.0将svg转换为png需要使用以下命令:
inkscape -w 1024 -h 1024 input.svg --export-file output.png

不是

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

1
我通过改变<svg>标签的widthheight属性以匹配我想要的输出大小,并使用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

4
为什么要将计算机生成的图像返回为JPEG格式? :( - Willi Mentzel

1

@808sound的最佳答案对我没有用。我想要调整大小 Kenney.nl UI Pack

结果是 Kenney UI Pack messed up

所以我打开Inkscape,然后转到文件导出PNG文件,一个GUI框弹了出来,让我设置我需要的确切尺寸。

Ubuntu 16.04 Linux版本: Inkscape 0.91 (2016年9月)

(顺便说一下,这个图片来自Kenney.nl的资源包


0

我使用增加密度的一般方法来获得“低多边形”曲线。所以我决定深入挖掘并解决这个问题,因为它似乎是这种方法的副作用,我认为它与原始密度或dpi有关。

我们在answer中看到72,在answer中看到96被建议作为图像的默认密度,但哪一个?如果我的不同怎么办?

ImageMagick有一种方法可以解决这个问题:

identify -verbose test.svg

这将提供有关图像文件的许多元数据,包括:

Image:
  Filename: test.svg
  Format: SVG (Scalable Vector Graphics)
  Mime type: image/svg+xml
  Class: ...
  Geometry: ...
  Resolution: 37.79x37.79
  Print size: ...
  Units: PixelsPerCentimeter
  # and a whole lot MORE ...

如果您想要更简洁的查询,可以尝试:

identify -format "%x x %y %U" test.svg
=> 37.789999999999999147 x 37.789999999999999147 PixelsPerCentimeter

此论坛帖子所建议,并结合文档进行修改

现在我们知道了图像的电流密度,但可能需要将其转换为正确的单位以进行转换或修改(每英寸像素数或dpi)

这是一个简单的计算公式:每厘米像素数 x 2.54

37.789999999999999147 x 2.54 = 95.9866 ~> 96

如果您喜欢使用图表或在线计算器,可以尝试https://www.pixelto.net/cm-to-px-converter

现在我们已经将正确的原始密度转换为dpi,上面的答案中提到的其余逻辑就会落实,svg文件可以通过乘以原始密度来缩放到更好的“分辨率”。

对我来说,原始密度作为png格式太过像素化了,因此在我的情况下,5倍的原始密度或-density 480就足够了。请记住,这也会调整图像的大小,因此在使用/实现图像时需要进行相应的调整,以与原始svg进行比较。

注意:我也尝试了Inkscape方法,并且也遇到了像素化问题,但是已经看到了密度方法的改进,因此我决定深入研究它。然而,Inkscape尝试的输出给了我一个想法,您也可以用它来确定dpi,但是安装它需要很多步骤,而ImageMagick已经可以做到这一点。

Area 0:0:20.75:17 exported to 21 x 17 pixels (96 dpi)

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