ChatGPT解决这个技术问题 Extra ChatGPT

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

我有一个定义大小为 16x16 的 SVG 文件。当我使用 ImageMagick 的转换程序将其转换为 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

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

例如 -size 1024x1024 工作正常,您的 imagemagick 版本是多少?
ImageMagick-6.9.0-Q16。 convert -resize 1024x1024 foo.svg foo.png 工作正常。
@Jichao -resize 只是拉伸了转换后的图像,结果质量很差。
convert -size 1024x1024 test.svg test.png 适用于 ImageMagick 7.0.7-0 Q16(Windows 的 Chocolatey 存储库中的当前版本)。只需确保 -size 出现在输入文件名之前,否则 16x16 图片将被放大以产生模糊的结果。

N
Nico Schlömer

在这种情况下,我无法从 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 的结果:

https://i.stack.imgur.com/ybxpA.png

https://i.stack.imgur.com/mDPMo.png


就imagemagick而言+1。 SVG 引擎似乎有问题。在大多数情况下,我无法使用它获得准确的结果。 Inkscape,OTOH,工作得非常好。
我认为 Inkscape 是继 Linux 之后最令人印象深刻的 OSS 示例。谢谢你的提示!
在 OSX 上也能很好地工作。
在 OSX 上,为 X11 安装了 Inkscape,它对我有用:/Applications/Inkscape.app/Contents/Resources/bin/inkscape -z -e test.png -w 1024 -h 1024 test.svg
@Rörd 要使用 ImageMagick 保持背景透明,请使用 -background none 命令行选项。
A
Ali Shakiba

试试 svgexport

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

svgexport 是一个简单的跨平台命令行工具,用于将 svg 文件导出为 jpg 和 png,请参阅 here 了解更多选项。要安装 svgexport install npm,然后运行:

npm install svgexport -g

编辑:如果您发现库有问题,请在 GitHub 上submit it,谢谢!


svgexport 对我很有用。输出匹配浏览器渲染比 ImageMagick 更接近。
这对我也很有效。与在 GUI 工具中手动执行相比,实时节省。无论如何,很难在 Mac 上找到一个能够很好地处理 SVG 且价格便宜的 GUI 应用程序
svgexport 在 OSX 上没有为我做任何事情,只是以空白图像结束
效果很好,但会产生巨大的图像。使用 optipng,我能够将我的文本徽标从 3 MB 压缩到 ~20kB。
evgexport 根据大小创建巨大的 png 文件。推荐 svg2png,它也使用 PhantomJS 进行导出,但创建的图像要小得多。
D
Dheeraj Bhaskar

这并不完美,但它可以完成工作。

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

基本上它增加了足够高的 DPI(只需使用有根据/安全的猜测),调整大小以足够的质量完成。我试图找到一个合适的解决方案,但一段时间后决定这足以满足我目前的需求。

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


在我的情况下,不透明度和阴影丢失了。
我没有复杂的 svg,所以这对我有用。 -resize 200% 不起作用,我必须以像素为单位指定大小。
@jiyinyiyong 要使用 ImageMagick 保持背景透明,请使用 -background none 命令行选项。为了保持图像比例,您也可以只指定一个维度,例如宽度为 -resize 200 或高度为 -resize x200。请参阅:imagemagick.org/script/command-line-processing.php#geometry 了解详尽的 ImageMagick 几何体 选项。
也不适合我。结果全是模糊的。
批处理版本为 for file in ./*.svg; do convert -density 1200 -background none -resize 200x200 $file `basename $file .svg`.png; done
J
Jose Alban

如果您在 MacOS X 上并且遇到 Imagemagick 的转换问题,您可以尝试使用 RSVG lib 重新安装它。使用自制:

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 确实将 svg 转换为 png,但结果毫无希望;重新安装后,它们是完美的。此外,转换速度明显更快。
这在 Mac OSX 上对我有用。我没有发现新的转换更快,但更准确。我强烈建议所有 Mac OSX 用户尝试一下。
这应该是公认的答案,哦。谢谢你,工作就像一个魅力,否则我永远不会知道采取这些步骤
在莫哈韦沙漠我得到 invalid option: --with-librsvg
@zaitsman 可能为时已晚,但是...参数选项已更改,请尝试使用 --with-rsvg。而且我认为它需要安装 librsvg2-bin 包。请参阅gist.github.com/maxivak/1476f7e979879da9f75371a86d5627b5
m
masterxilo

当 svg 单位不是 px(例如 cm)时,Inkscape 似乎不起作用。我得到一个空白图像。也许,可以通过调整dpi来解决,但是太麻烦了。

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

Imagemagick 的转换适用于:

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

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

最好的

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

它速度最快,依赖项最少,输出比 convert 小 30% 左右。安装 librsvg2-bin 得到它:

sudo apt install -y librsvg2-bin

似乎没有手册页,但您可以键入:

rsvg-convert --help

获得一些帮助。简单就好。


这很容易是最好的答案(我不知道为什么二十个不同的答案会给出相同的 imagemagick 响应);它保留了颜色和阴影,并且不会破坏任何东西。但是,为了匹配 imagemagick 调整大小的行为(特别是,WxH 表示缩放图像以适合该大小的框,保持纵横比),-a 参数应与 rsvg 一起使用。
这破坏了我的图像,各种奇怪的文物。 inkscape 做得更好。
仅供参考,当前安装命令是 brew install librsvg,转换命令是 rsvg-convert
在将复杂的 svg 转换为 png 时,我发现 librsvg(或在 Arch 的情况下为 rsvg-convert)提供最佳和最一致的结果。跟进 optipng 以减小输出文件大小。
在 Ubuntu 中:sudo apt install librsvg2-bin; rsvg-convert input.svg -o output.png
J
João Pimentel Ferreira

执行 Jose Alban's answer 中的步骤后,我可以使用以下命令让 ImageMagick 正常工作:

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

数字 1536 来自对密度的粗略估计,有关详细信息,请参阅 this answer


改用 -size,显然在某些 IM 版本中调整大小会使图像模糊
w
waldyrious

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

convert -density 144 source.svg target.png

请注意,转换选项必须在输入文件之前。即 convert source.svg -density 144 target.png 不会重新缩放图像。
实际上标准密度似乎是 90。所以它会是 convert -density 180 source.svg target.png
f
fmw42

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

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

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

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

convert button.svg button1.png

https://i.stack.imgur.com/4PmEW.png

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

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

convert -density 983 button.svg button2.png

https://i.stack.imgur.com/885O6.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

+1 用于避免单独命令或使用计算器的神奇 fx 表达式。附带说明一下,如果您运行 identify -format "%x x %y (%w x %h) file.svg,您还将在输出中获得默认密度的宽度和高度(公式中的 $in_size 需要)!
你甚至可以在 1 行中做到这一点stackoverflow.com/a/66901038/1597158
谢谢!它就像一个魅力!如果您添加选项 -background none,您还将拥有一个具有透明背景的 .png!
m
mloughran

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

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

许多选项可通过 rsvg-convert --help


M
MestreLion

对于简单的 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",第 39 行,在 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 raise OSError("dlopen() failed to load a library: %s" % ' / '.join(names)) OSError: dlopen() failed to load a library: cairo / cairo-2 / cairo-gobject-2 / cairo.so.2
很好,Ubuntu-19.04 上的 cairosvg 为我完成了这项工作。
我只想写:多么出色的解决方案!第一个 PNG 看起来很棒,但其他的则不然。相反,我必须写:这完全取决于提供最佳质量的 SVG 解决方案。
a
ampecs

你为什么不尝试一下 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"


S
Shivam

这对我有用,也是最容易运行的。

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

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

确保您已安装 librsvg 并重命名 util

brew install librsvg
brew install rename

q
qubodup

透明背景,使用 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,但这非常有效。
我不得不使用 convert,但除此之外它工作得很好 (convert -background none -size x1080 in.svg out.png)。
Q
Qohelet

我来到这篇文章 - 但我只是想在不使用任何参数的情况下批量快速地进行转换(由于几个文件的大小不同)。

rsvg drawing.svg drawing.png

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


作为参考,在 macOS 上,它与 brew install librsvg 一起安装,转换命令为 rsvg-convert
在 Ubutni 它也是 rsvg-convert,包是 librsvg2-bin 并且输出需要 -o drawing.png
C
Community

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

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


我没有安装这个库,也没有得到黑色图像。
N
Nick

让我感到震惊的一件事是在输入文件名之后设置 -density。那没有用。将它移到 convert 中的第一个选项(在其他任何东西之前)使它工作(对我来说,YMMV 等)。


s
sbkm

在 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

Y
Yanone

我通过更改 <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

你为什么要将计算机生成的图像返回为 jpeg :(?
J
James L.

https://i.stack.imgur.com/RTFHn.png

https://i.stack.imgur.com/Q7fxS.png

因此,我打开了 Inkscape,然后转到 FileExport as PNG file 并弹出一个 GUI 框,让我可以设置所需的确切尺寸。

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

(顺便说一下,这张图片来自Kenney.nl's asset packs


S
SMAG

我使用增加密度的一般方法得到“低多边形”曲线。所以我决定深入挖掘并解决这个问题,因为它似乎是这种方法的副作用,我认为它与原始密度或 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

按照 this forum post 的建议并使用此 documentation 进行修改

现在我们知道图像的当前密度,但可能需要将其转换为正确的单位以进行转换或修改(PixelsPerInch 或 dpi)

这是 PixelsPerCentimeter x 2.54 的简单计算

37.789999999999999147 x 2.54 = 95.9866 ~> 96

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

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

原始密度对我来说太像素化了,所以在我的情况下,原始密度的 5 倍或 -density 480 对我来说已经足够了。请记住,这也会调整图像的大小,与原始 svg 相比,您在使用/实现图像时需要对此进行调整。

注意:我也尝试过 Inkscape 方法,但也遇到了像素化问题,但已经看到密度方法的改进,所以我决定深入研究。然而,Inkscape 尝试的输出给了我一个想法,您也可以使用它来确定 dpi,但是为了获得 ImageMagick 已经可以得到的东西,需要安装很多东西

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