Convert SVG to transparent PNG with antialiasing, using ImageMagick
Asked Answered
C

8

88

I want to convert SVG images to PNG files with transparent background and anti-aliased edges (using semi-transparent pixels). Unfortunately I can't get ImageMagick to do the anti-aliasing, the edges always look terrible. Here's what I tried:

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

Any ideas or a different command line tool I could use?

Contactor answered 2/3, 2012 at 9:3 Comment(0)
C
60

Inkscape will do this:

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

Update

The terminology has changed: all the export params suppress gui, and the output parameter is now simply based on the file type. For example, a type of png will cause a file in /path/to/picture.svg to be exported as /path/to/picture.png (caution: this overwrites output).

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

Note cited wiki has quotes on --export-type=png, which is incorrect.

Also if don't have Inkscape command line, MacOS can access via bash directly:

/Applications/Inkscape.app/Contents/MacOS/inkscape
Conjugation answered 5/3, 2012 at 16:18 Comment(6)
The first solution I've found that keeps the color palette of some SVGs, e.g. the logo of Apache NiFi (nifi.apache.org/assets/images/apache-nifi-logo.svg).Brina
Imagemagick now will use Inkscape if it is installed on the system. You have the choice of: Inkscape (if on the system), RSVG delegate (must be installed with Imagemagick, or the Imagemagick internal MSVG/XML.Equate
The "supply -background none before the SVG filename" answer is much better because it actually uses ImageMagick, the tool asked about…: https://mcmap.net/q/236710/-convert-svg-to-transparent-png-with-antialiasing-using-imagemagickKlimt
@FredrickBrennan: my general view is that readers (and question authors) will use the tool that gives them the best results. If an OP is made that asks how to knock in a nail with a screwdriver, sometimes an answer that recommends a hammer anyway is best, even if it is "not what they asked for".Conjugation
(Nice to hear there's more than one way to do it though 😌).Conjugation
Well, since user said they needed command line tool, I assume servers are involved, and ImageMagick is easier is much easier to run on servers, not requiring a little of Xorg dependencies. But yes, OK.Klimt
H
134

Instead of -background transparent, use -background none.

convert -background none in.svg out.png

NOTE: The order of the arguments is important.

Heliotrope answered 2/9, 2013 at 19:10 Comment(8)
At least at this time (6.8.6), it works with transparent too.Bazil
Both 'none' and 'transparent' create opaque white background for me. Not transparent. I'm using 6.8.8-3 on MacPrintmaker
-background none worked for me, ImageMagick 6.8.6-6 on a macOrdain
@Printmaker although the command will accept the input image path as the first argument (e.g. convert in.svg -background none out.png, I found that this ordering will fail to make the background transparent; it resulted in an opaque white background! Make sure that in.svg and out.png are the final two arguments in the command.Musk
This removed the color palette of a SVG I tried to convert (nifi.apache.org/assets/images/apache-nifi-logo.svg).Brina
-background none is indeed correct as per the image magic color names documentation: "There is also a color called 'none' that is fully transparent. This color is shorthand for rgba(0, 0, 0, 0.0)."Vincents
this works! if it doesn't you probably have a background inside of your SVG that you're unaware of! That took me a while to find out lol...Krugersdorp
If it isn't working for your SVG, check whether the SVG is using style attributes (like style="fill:#ff0000;stroke:#000") and try changing them to attributes: fill="#ff0000" stroke="#000"Merola
C
60

Inkscape will do this:

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

Update

The terminology has changed: all the export params suppress gui, and the output parameter is now simply based on the file type. For example, a type of png will cause a file in /path/to/picture.svg to be exported as /path/to/picture.png (caution: this overwrites output).

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

Note cited wiki has quotes on --export-type=png, which is incorrect.

Also if don't have Inkscape command line, MacOS can access via bash directly:

/Applications/Inkscape.app/Contents/MacOS/inkscape
Conjugation answered 5/3, 2012 at 16:18 Comment(6)
The first solution I've found that keeps the color palette of some SVGs, e.g. the logo of Apache NiFi (nifi.apache.org/assets/images/apache-nifi-logo.svg).Brina
Imagemagick now will use Inkscape if it is installed on the system. You have the choice of: Inkscape (if on the system), RSVG delegate (must be installed with Imagemagick, or the Imagemagick internal MSVG/XML.Equate
The "supply -background none before the SVG filename" answer is much better because it actually uses ImageMagick, the tool asked about…: https://mcmap.net/q/236710/-convert-svg-to-transparent-png-with-antialiasing-using-imagemagickKlimt
@FredrickBrennan: my general view is that readers (and question authors) will use the tool that gives them the best results. If an OP is made that asks how to knock in a nail with a screwdriver, sometimes an answer that recommends a hammer anyway is best, even if it is "not what they asked for".Conjugation
(Nice to hear there's more than one way to do it though 😌).Conjugation
Well, since user said they needed command line tool, I assume servers are involved, and ImageMagick is easier is much easier to run on servers, not requiring a little of Xorg dependencies. But yes, OK.Klimt
R
19

Actually, reading imagemagick documentation:

-antialias

Enable/Disable of the rendering of anti-aliasing pixels when drawing fonts and lines. By default, objects (e.g. text, lines, polygons, etc.) are antialiased when drawn. Use +antialias to disable the addition of antialiasing edge pixels. This will then reduce the
number of colors added to an image to just the colors being directly drawn. That is, no mixed >colors are added when drawing such objects.

the +antialias will indeed disable antialiasing.

Rizzo answered 30/5, 2012 at 10:37 Comment(1)
They got it backwards :|Pannikin
R
12

The way I learned how to do this was from the methodology found here: How to convert a .eps file to a high quality 1024x1024 .jpg?

It is the same idea as @halfer's solution with inkscape--to jack up the DPI first--but you can accomplish the same thing in just imagemagick using the -density option.

convert -density 200 in.svg -resize 25x25 -transparent white out.png
Ramsden answered 11/1, 2015 at 10:59 Comment(1)
This solution, while it may work for many SVG files, is inferior to the -background none solution, because white is a valid fill/stroke color that may present in many SVG's, and this turns all white pixels transparent, even those defined as being white fills/strokes.Klimt
S
5

Adding the -transparent white option solves the problem particularly in my case because background isn't removed completely (unfortunately light shadow is present). So I'm using IMHO more clearer solution that fully removes background with ImageMagic:

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

It sets a fully transparent black color as the background through the RGBA channel.

Smote answered 18/9, 2018 at 23:7 Comment(3)
This is the relevant documentation for the -transparent option: imagemagick.org/script/command-line-options.php#transparentVincents
After fiddling with it for a while, this was the only way to get it to work - much appreciated!Sletten
-background none works just as well in recent IM releases, and avoids needing to supply -channel rgba if the target is PNGKlimt
C
5

For me that works for svg to png:

convert ${src} \
    -transparent white \
    -background none \
    -resize 345x345 \
    res/drawable-xxxhdpi/${dest}
Copalm answered 25/4, 2020 at 14:35 Comment(1)
There is no reason to supply both -transparent white and -background none, and this will negatively effect files with elements of the foreground that are supposed to be white. Only supply -background none.Klimt
G
0

I get better, already nicely antialiased results if I replace -resize with -scale. Then, the antialias flag isn't even necessary.

Goosegog answered 21/9, 2019 at 9:5 Comment(0)
N
-1

I add a rect as background. The embed CSS hide the background. Then I catch its color for setting the transparent attribute of ImageMagick.


SVG file:

<?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 script

#!/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
Nitrosamine answered 5/10, 2018 at 11:56 Comment(3)
Rube Goldberg would be proud.Klimt
I'm sorry @FredrickBrennan, I do not understand. Did you tried without the background rect on Imagick?Bovine
Yes, you only need -background none option to convert.Klimt

© 2022 - 2024 — McMap. All rights reserved.