Convert SVG to transparent PNG with antialiasing, using ImageMagick

SvgImagemagickPngInkscape

Svg Problem Overview


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?

Svg Solutions


Solution 1 - Svg

As a side note, I found that getting transparency was a bit tricky. Instead of using transparent, I had to use none.

convert -background none in.svg out.png

Solution 2 - Svg

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

Solution 3 - Svg

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.

Solution 4 - Svg

The way I learned how to do this was from the methodology found here: https://stackoverflow.com/questions/7583821/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

Solution 5 - Svg

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.

Solution 6 - Svg

For me that works for svg to png:

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

Solution 7 - Svg

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

Solution 8 - Svg

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAndreas GohrView Question on Stackoverflow
Solution 1 - SvgMicahView Answer on Stackoverflow
Solution 2 - SvghalferView Answer on Stackoverflow
Solution 3 - SvgsleeperView Answer on Stackoverflow
Solution 4 - SvgchiliNUTView Answer on Stackoverflow
Solution 5 - SvgYurii RabeshkoView Answer on Stackoverflow
Solution 6 - SvgyourstrulyView Answer on Stackoverflow
Solution 7 - SvgC WürtzView Answer on Stackoverflow
Solution 8 - SvgWoodrowShigeruView Answer on Stackoverflow