将SVG转换并调整大小为PNG

39

我希望将SVG转换为PNG(或任何光栅格式)并同时调整大小。

我想使用ImageMagick来完成此任务,但它似乎在调整大小之前就将图像转换为了光栅格式。

这会导致图像质量不佳。

  • 是否有办法让ImageMagick在将SVG转换为光栅格式之前先调整大小?

  • 还是有其他工具可以在调整大小后进行SVG到光栅格式的程序转换吗?

  • 或者,还有其他工具可供使用吗?

目前,我是通过命令行使用ImageMagick:

convert file.svg -resize 100x100 file.png

源图像的"size"未知,目标大小直到运行时才知道。


展示一下你正在输入的命令。 - Tarik
@Tarik 我添加了错误的命令行 - DJL
@MarkSetchell的回答是正确的。您需要在命令行中提前设置画布大小。有关ImageMagick命令结构和其参数顺序的更多详细信息,请参见"ImageMagick命令行选项顺序(和命令行参数类别)" - Kurt Pfeifle
https://dev59.com/bmkw5IYBdhLWcg3wfKrZ - Ciro Santilli OurBigBook.com
7个回答

51

这是我做事的方式,看起来似乎行得通。

convert -background none -density 1000 -resize 1000x compass.svg compass.png

以下是每个部分的作用。

  • 使用-background none确保SVG的任何透明部分保持透明,不会被填充为白色。
  • 由于ImageMagick只能处理光栅图像,因此您需要使用-density 1000并指定要将SVG调整大小到的宽度。这样,当您实际调用调整大小命令时,加载的SVG的光栅表示已经具有宽度为1000,否则您将以原始SVG图像的任意大小调整光栅的大小。
  • 现在使用-resize 1000x赋予您的SVG新的宽度,高度将自动计算以保持纵横比。

其中一个问题是,我不知道如何基于高度调整大小并让宽度计算,因为-density应用于宽度而不是高度。因此,您必须事先知道SVG的实际比率,并相应地处理宽度。


2
"-density x" 是使其比默认值更大的缺失部分。 - robjtede

41

SVG被定义为矢量图形,而不是位图 - 这是IM希望处理的内容。当IM读入一个矢量图形时,它不知道大小,所以当您执行以下操作时:

convert compass.svg -resize 1000x1000 compassB.jpg

它创建了一个默认大小的位图画布,将矢量图绘制到画布上,然后调整大小并将其保存为JPEG。如果您预定的尺寸大于IM“猜测”的画布,则结果质量较差——因为将图像栅格化到太小的画布上会导致丢失信息。

输入图像描述

解决方案是在光栅化之前告诉IM需要将向量绘制到大画布上:

convert -size 1000x1000 compass.svg compassA.jpg

在这里输入图片描述


那很有道理。我会研究一下,谢谢。 - DJL
@DJL:这是正确的答案。如果您不接受它,请至少点赞! - Kurt Pfeifle
@KurtPfeifle,等我有机会检查一下后再回复你。这个问题是6个月前提出的,我现在已经做其他事情了。 - DJL
7
我无法让这个工作起来。可能是我的ImageMagick版本太旧了。 - DJL
4
我也试过了,这并不起作用。图像以其原始大小(在XML中定义的大小)保存。 - Tony Bogdanov
显示剩余2条评论

12

我已经使用svgexport来完成这个任务:

svgexport file.svg file.png 100:100

这是一个很棒的工具,但不幸的是我不能再使用它了,因为它依赖于已被弃用的PhantomJS。 - Aslan French

5
所以事实证明Inkscape有一个命令行界面。不幸的是,Inkscape的-w和-h参数不能保持纵横比。然而它确实提供了一种查询当前宽度和高度的方法,但只能一次查询一个。因此,解决方案是运行Inkscape不少于3次。
inkscape -f svgfile.svg -W
<read stdin into some variable>
inkscape -f svgfile.svg -H
<read stdin into some variable>
<calculate aspect ratio and apply logic to retain aspect for new size>
inkscape -f svgfile.svg -w <newwidth> -h <newheight> -e file.png

在我的情况下,我需要通过ImageMagick运行生成的文件来执行其他操作。

用C#完成所有这些工作非常繁琐,因此我仍在寻找更好的解决方案。


3
使用ImageMagick 7,您可以在一行代码中执行以下操作:
magick in.svg -density "%[fx:((1080/w)*72)]" -delete 0 -background none in.svg -scale 1080x out.png

这将自动确定正确的密度以使其缩放到正确的分辨率。将2个'1080'值替换为您喜欢的png宽度。

不错。如果我将72更改为96,我就不需要-scale 1080x步骤了。完整命令:magick in.svg -density "%[fx:((1080/w)*96)]" -delete 0 -background none in.svg out.png - Robin A. Meade

1

值得注意的是,ImageMagick在过去的10年里发生了相当大的变化。可能这就是你看到不同结果的原因。 - DJL

0

很奇怪的是,ImageMagick会以一种尺寸进行渲染,然后重新调整位图。除非SVG中定义了特定的大小。检查您正在使用的SVG文件的widthheight属性。尝试将宽度和高度更改为100%,看看是否有所不同。

<svg width="100%" height="100%" ...etc...>

(假设您可以控制您所使用的SVG文件)。


这是一个有趣的解决方案。我还没有尝试过,因为我已经用另一种方式解决了这个问题(虽然相当复杂)。答案将在几分钟内给出。不幸的是,我无法控制源SVG。 - DJL

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