使用ImageMagick将SVG转换为带有抗锯齿的透明PNG

86

我想将SVG图像转换为带有透明背景和反锯齿边缘(使用半透明像素)的PNG文件。不幸的是,我无法让ImageMagick进行抗锯齿处理,边缘看起来总是很糟糕。这是我尝试过的:

convert +antialias -background transparent  in.svg -resize 25x25 out.png

有什么想法或者我可以使用不同的命令行工具吗?

8个回答

133

使用-background none代替-background transparent

convert -background none in.svg out.png

注意:参数的顺序很重要。


至少在目前版本(6.8.6)中,它也可以与“transparent”一起使用。 - Martin Poljak
6
“none”和“transparent”都给我创建了不透明的白色背景,而不是透明的。我正在Mac上使用6.8.8-3版本。 - petrsyn
4
在我的电脑上,ImageMagick 6.8.6-6版本,使用“-background none”命令可以成功执行。 - commonpike
44
尽管该命令将输入图像路径作为第一个参数接受(例如,convert in.svg -background none out.png),但我发现这种顺序会导致背景不透明;结果是一个不透明的白色背景!请确保 in.svgout.png 是命令中的最后两个参数 - kostmo
1
根据Image Magic的颜色名称文档,"-background none"是正确的:*"还有一种名为'none'的颜色是完全透明的。这种颜色是rgba(0, 0, 0, 0.0)的简写。"* - icc97
显示剩余3条评论

61

Inkscape可以做到这一点:

inkscape \
    --export-png=out.png --export-dpi=200 \
    --export-background-opacity=0 --without-gui in.svg

更新

术语已经更改:所有导出参数都会抑制GUI界面,输出参数现在根据文件类型简单确定。例如,png 类型将导致将 /path/to/picture.svg 文件导出为 /path/to/picture.png(注意:这将覆盖输出文件)。

inkscape \
    --export-type=png --export-dpi=200 \
    --export-background-opacity=0 picture.svg

请注意引用的维基页面中关于 --export-type=png 的引述是错误的。

如果没有Inkscape命令行,MacOS可以直接通过bash访问:

/Applications/Inkscape.app/Contents/MacOS/inkscape

1
我找到的第一个解决方案可以保留一些SVG的颜色调色板,例如Apache NiFi的标志(https://nifi.apache.org/assets/images/apache-nifi-logo.svg)。 - timss
2
Imagemagick现在将使用Inkscape(如果系统上已安装)作为选择之一:Inkscape(如果系统上已安装),RSVG代理(必须与Imagemagick一起安装)或Imagemagick内部MSVG/XML。 - fmw42
“在 SVG 文件名之前添加「-background none」选项的答案更好,因为它实际上使用了被询问的工具 ImageMagick…”:https://dev59.com/FGkw5IYBdhLWcg3w9_Qi#18579465 - Fredrick Brennan
@FredrickBrennan:我的一般观点是,读者(和问题作者)将使用给他们最佳结果的工具。如果有人发布了一个问题,问如何用螺丝刀敲钉子,有时候推荐使用锤子的答案仍然是最好的,即使它“不是他们要求的”。 - halfer
很高兴听到有不止一种方法可以做到这一点。 - halfer
1
既然用户说他们需要命令行工具,我假设涉及到服务器,并且ImageMagick更容易在服务器上运行,不需要太多的Xorg依赖。但是,好的。 - Fredrick Brennan

19

实际上,阅读 ImageMagick 文档:

-antialias

绘制字体和线条时启用/禁用反锯齿像素的渲染。默认情况下,对象(例如文本、线条、多边形等)在绘制时是抗锯齿的。使用 +antialias 来禁用添加反锯齿边缘像素。这将减少添加到图像中的颜色数量,仅限于直接绘制的颜色。也就是说,在绘制此类对象时不会添加混合颜色。

+antialias 将确实禁用反锯齿效果。


他们搞反了 :| - Iulian Onofrei

12

我学习这种方法是从这里找到的方法:如何将 .eps 文件转换为高质量的 1024x1024 .jpg?

这与 @halfer 的解决方案相同,使用 inkscape 来提高 DPI,但你可以仅使用 imagemagick 并使用 -density 选项来完成相同的事情。

convert -density 200 in.svg -resize 25x25 -transparent white out.png

这个解决方案可能适用于许多SVG文件,但是它不如“-background none”解决方案好,因为白色是许多SVG中可能出现的有效填充/描边颜色,这会将所有白色像素变成透明,即使那些定义为白色填充/描边的像素也会被转换。 - Fredrick Brennan

5

对我而言,以下方法可将SVG转换为PNG:

convert ${src} \
    -transparent white \
    -background none \
    -resize 345x345 \
    res/drawable-xxxhdpi/${dest}

没有理由同时提供“-transparent white”和“-background none”,这会对具有前景元素应该是白色的文件产生负面影响。只需提供“-background none”。 - Fredrick Brennan

5

在我的情况下,添加-transparent white选项 特别解决了问题,因为背景没有完全被移除(不幸的是还有轻微的阴影)。因此,我使用了更清晰的解决方案,可以完全去除背景,使用 ImageMagic:

convert -channel rgba -background "rgba(0,0,0,0)" in.svg out.png

它通过 RGBA 通道设置完全透明的黑色背景。


这是-transparent选项的相关文档:http://www.imagemagick.org/script/command-line-options.php#transparent - icc97
2
折腾了一会儿,这是唯一让它工作的方法 - 非常感谢! - Domi
1
"-background none" 在最近的 IM 版本中同样有效,并且避免了在目标为 PNG 时需要提供 "-channel rgba"。 - Fredrick Brennan

0

如果我用-scale替换-resize,就可以得到更好的抗锯齿效果。这样,antialias标志甚至都不必要了。


-1

我添加了一个矩形作为背景。 嵌入的CSS隐藏了背景。 然后我捕获它的颜色,以设置ImageMagick的透明属性。


SVG 文件:

<?xml version="1.0" ?>
<!DOCTYPE svg  PUBLIC '-//W3C//DTD SVG 1.1//EN'  'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
<svg 
    version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
    width="500px" height="500px"
    viewBox="0 0 500 500" 
    enable-background="new 0 0 500 500" 
    >
<defs>
    <style>
        #background { display: none; }
    </style>
</defs>
<rect id="background" x="0" y="0" width="500" height="500" fill="#e8e437"/>
<!-- beginning of the sketch -->
<g fill="#000" text-anchor="middle"font-size="112">
    <text y="350" x="192">OK</text>
</g>
<!-- end of the sketch -->
</svg>

bash脚本

#!/bin/bash


BASE_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )
SVG_DIR="$BASE_DIR/import"
PNG_DIR="$BASE_DIR/export"

for f in `ls $SVG_DIR/*.svg`
do
    g="$PNG_DIR/$(basename "$f" .svg).png"
    BGCOLOR=`grep 'id="background"' $f \
        | sed 's/.* fill="\([^"]*\)".*/\1/'`

    convert $f -transparent "$BGCOLOR" $g
done

2
鲁布·戈尔德会感到自豪。 - Fredrick Brennan
抱歉@FredrickBrennan,我不明白。 你尝试过在Imagick上去掉背景矩形吗? - C Würtz
是的,您只需要在“convert”命令中添加“-background none”选项。 - Fredrick Brennan

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