277

Are there any command-line programs that can convert an SVG to PNG that run on macOS?

Lorin Hochstein
  • 4,287
  • 6
  • 29
  • 26
  • 2
    I found a way if you have Google Chrome... and no need to install any other things: http://superuser.com/questions/134679/command-line-application-for-converting-svg-to-png-on-mac-os-x/1036841#1036841 – nonopolarity Feb 07 '16 at 19:06
  • https://cairosvg.org/ works for python3 and seems to have no issue. `pip3 install cairosvg` – JayRizzo May 24 '19 at 20:31

22 Answers22

335

Or without installing anything:

qlmanage -t -s 1000 -o . picture.svg 

It will produce picture.svg.png that is 1000 pixels wide.

I have tested it only on OS X 10.6.3.

tst
  • 3,546
  • 1
  • 15
  • 2
  • 56
    Unfortunately this clips images to a square. – Martijn Pieters Jan 30 '11 at 15:13
  • 10
    Ah, `qlmanage -t` gives the thumbnail used by Quick Look (in Finder, etc). Clever idea. Unfortunately, these thumbnails can be buggy, especially when there's text involved. – ShreevatsaR Jun 06 '11 at 08:07
  • 8
    This produces images with the svg file in the 1st quadrant. Doesn't auto crop. Trying to convert files from noun project - wish this worked. – Alex Cook Nov 12 '12 at 20:40
  • It will also not scale down the image to fit everything within the specified width. – Johan Feb 21 '14 at 17:48
  • One other note is that it did not preserve the transparent background of my image... still quite handy and worked for me otherwise! :) – Drewdavid Nov 03 '14 at 21:19
  • 1
    Any way to do this without it adding a white background? – sudo Jun 25 '15 at 00:19
  • 19
    This solution fails to take transparency into account. The tool `rsvg-convert` in @ahti's answer worked out before for me. – TommyMason May 19 '16 at 08:30
  • 2
    the -s option takes dimensions in the form "-s 1920x1080" so you can specify the precise dimensions you want. It seems like the image is not clipped if you specify full dimensions. – Arkain Jul 12 '16 at 16:16
  • is there any way to tell qlmanage to use a specific density? man revealed nothing. – computingfreak Aug 22 '17 at 07:10
  • 6
    Putting both width and height parameters after the `-s` option didn't work for me. Still crops it to a square. Very frustrating! – Erik van der Neut Aug 25 '17 at 07:45
  • 2
    transparency doesn't seem to work – theonlygusti Jan 21 '18 at 13:07
  • Never heard of this tool. Can one comment on this please? (It worked) – stephanmg Dec 17 '20 at 20:19
  • If the SVG has a border this tool will correctly capture the top and left border but will cut off the right side and bottom of the image. – cschroed Mar 18 '21 at 14:01
211

I found that for me the best tool for the job is rsvg-convert.

It can be found in brew with brew install librsvg and is used like this:

rsvg-convert -h 32 icon.svg > icon-32.png

This example creates a 32px high png. The width is determined automatically.

Senseful
  • 4,150
  • 10
  • 37
  • 46
Ahti
  • 2,219
  • 1
  • 13
  • 6
  • 2
    This is the only one that worked for me on Mavericks and https://commons.wikimedia.org/wiki/File:Windows_logo_-_2012_derivative.svg – Aron Ahmadia Jun 10 '14 at 01:03
  • 1
    Actually this one worked, while ImageMagick's `convert` issued errors and failed to covert a complex SVG – bric3 Apr 27 '15 at 10:03
  • 16
    This is by far the best solution I've found for OS X Yosemite +1! – Greg Martin May 09 '15 at 15:03
  • This failed for some of my SVGs, strangely. The `qlmanage` answer worked for all of them but put a white background, which I don't want. – sudo Jun 25 '15 at 00:35
  • If some of your SVGs don't work with this (and you are sure the files are not faulty), consider filing a bug with the librsvg project (https://wiki.gnome.org/Projects/LibRsvg) – Ahti Jun 29 '15 at 14:10
  • This answer worked for me on OS X 10.10, while the imagemagick answer didn't. –  Aug 05 '15 at 16:06
  • @sudo Try normalizing the SVGs using `hxnormalize` from `brew install html-xml-utils`. – Lenar Hoyt Dec 14 '15 at 23:56
  • The best solution because it uses a very good rasterizer in terms of resolution. – Paul-Sebastian Manole May 17 '17 at 12:21
  • And remember automator is your friend if you have to do a whole bunch: ask for finder items, run shell script passing input as argument, then something like ```PATH=/usr/local/bin:/bin export PATH for filename in "$@" do finalFilename="${filename%.svg}.png" rsvg-convert -h 300 "$filename" > "$finalFilename" done``` – Zoë Smith Jul 07 '17 at 16:45
  • `rsvg-convert` has parameters `-d (x-dpi)` and `-p (y-dpi)`, to allow user to control density during export – computingfreak Aug 22 '17 at 07:12
  • 2
    With `rsvg-convert`, the resulting .png had the right dimensions, but the image came out all black instead of the original colors. With `qlmanage` the image is cropped to a square. Still searching for a solution :-( – Erik van der Neut Aug 25 '17 at 07:47
  • Where the SVG has overlapping semi-transparent elements, these are not rendered correctly. FWIW Affinity Photo has the same problem. – Paul Masri-Stone Jun 01 '18 at 13:42
  • 4
    Batch converting like this `find . -type f -name "*.svg" -exec bash -c 'rsvg-convert -h 800 "$0" > "$0".png' {} \;` – MikeiLL Oct 30 '19 at 18:45
  • `rsvg-convert` will not trim blank around png file. use `convert image.png -trim output.png` to trim them. – Anyany Pan Apr 01 '20 at 08:01
  • As of April 2020, rsvg-convert has no current release via homebrew. – Tom Apr 21 '20 at 06:57
  • @Tom what do you base that on? The latest available version is 2.48.3 (according to https://download.gnome.org/sources/librsvg/2.48/), which has been available in brew since the 10th of April, one day after it was released (https://github.com/Homebrew/homebrew-core/pull/52815). – Ahti Apr 23 '20 at 01:24
  • 1
    @Ahti You're correct! I failed to note the proper package name in your answer. Your instructions work perfectly when followed correctly, and rsvg-convert works like a charm. I'm sorry for the trouble. – Tom Apr 23 '20 at 02:09
  • This works on OS X Mojave with no cropping. It also outputs all of used canvas and does auto height/width trimming. I find this useful to export large canvas drawings as SVG over PNG/PDF from iPad apps, e.g., Concepts app which otherwise crash exporting larger drawings as PNG/PDF. – Samir May 14 '20 at 05:13
  • Installation is failing for me with `Error: An exception occurred within a child process: FormulaUnavailableError: No available formula with the name "/usr/local/opt/python@2/.brew/python@2.rb"` – BlkPengu Aug 16 '20 at 18:44
  • The only one that worked for me on macOS Monterey without getting trash output. – Martin Braun Nov 26 '21 at 22:08
  • Best solution, this should be the accepted answer. – Riveascore Mar 09 '22 at 21:30
70

ImageMagick is an extremely versatile command-line image editor, which would probably rival Photoshop if it had, you know, a GUI. But who needs those anyways. :P

Something like the following would convert a .svg to .png, after installation:

$ convert picture.svg picture.png

The original .svg isn't deleted.

Glorfindel
  • 4,089
  • 8
  • 24
  • 37
Jessie
  • 1,992
  • 11
  • 10
  • It *sort of* has a GUI, in `display`. – Ignacio Vazquez-Abrams Apr 26 '10 at 04:04
  • 2
    When I installed ImageMagick with Fink, I couldn't convert svg to png - there were some errors. It turned out that I needed to install librsvg2-bin as well. – tst May 21 '10 at 12:44
  • If librsvg2-bin isn't installed (like on OS X) this will fail. Couldn't find a way to get that installed on OS X. – John Sheehan Aug 03 '12 at 18:53
  • 3
    This won't work well if you want to resize the SVG as it generates blurry images. – Behrang May 23 '13 at 03:04
  • 4
    It doesn't convert all SVG files correctly either; at least qlmanage got all the parts of the image. – Johan Feb 21 '14 at 19:50
  • Even using -density the export is weird. I thought my SVG were of poor quality (all circles were in fact polygons) using rsvg-convert worked much better! – AsTeR Oct 22 '14 at 13:10
  • This is the only one that works for all SVGs for me. The quality seems nice, unless I'm missing something. I used -density 600. – sudo Jun 25 '15 at 01:12
  • For an 800kb SVG file, imagemagick has already used 15 minutes of CPU time and is still going. This is not ideal. I usually like using ImageMagick. – Dave Cameron Jul 29 '19 at 16:46
  • I've never had issues with imagemagick on linux systems, but on mac it creates blurry or blank output – theferrit32 Aug 13 '20 at 19:04
  • Gradients don't work correctly. – cschroed Mar 18 '21 at 13:55
  • this doesn't seem to generate transparent backgrounds for me. everything is white. are there some options? – dcsan Apr 11 '21 at 11:47
  • imagmagick's convert seems to just use rsvg-convert (librsvg2-bin) under the hood. – Collin Anderson Jul 01 '22 at 15:16
  • I was excited to use imagemagick for this, but it did not capture all the elements of my SVG in the output :/ – oclyke Sep 24 '22 at 19:52
  • does not work if you need transparency or gradients. Issue is described here: https://stackoverflow.com/q/28332339/804521 – Yevgeniy M. Mar 18 '23 at 11:06
37

Inkscape with it's Commandline-Interface produces the best results for me:

Install Inkscape:

brew install inkscape

Convert test.svg to output.png with a width of 1024 (keep aspect ratio):

/Applications/Inkscape.app/Contents/MacOS/inkscape --export-type png --export-filename output.png -w 1024 test.svg

OLD ANSWER (doesn't work anymore with latest inkscape):

/Applications/Inkscape.app/Contents/Resources/bin/inkscape --export-png output.png -w 1024 -h 768 input.svg*
daxlerod
  • 3,125
  • 3
  • 21
  • 23
seb
  • 479
  • 4
  • 4
33

OK, I found a simple way to do it on the Mac if you have Google Chrome.

(and this works even if it is to convert a webp file in Chrome to png or jpg)

In one sentence, it is to see the svg image in a webpage (must be in an html file), right click on image and choose "Copy Image" and paste to the Preview app.

Steps:

  1. Download or have the svg file in your hard drive, say, somefile.svg
  2. Now, in the same folder, just make an html file tmp.html that contains this line: <img src="somefile.svg">
  3. Now, open that html file in Google Chrome
  4. You should see the image. Now just right click on the image and choose "Copy Image"
  5. Go to Mac's Preview App, and choose, "File -> New from Clipboard"
  6. Now File -> Save the file and you have the png file. (or other file types).

This is tested on the current Chrome (version 48.0) on Mac OS X El Capitan.

Update: I am not sure whether it is due to some restriction imposed by Google Chrome. I just try an SVG file using Chrome 58.0, and I get a tiny image from the method above. If you see this case too, you can also use

<img src="somefile.svg" style="height: 82vh; margin-top: 9vh; margin-left: 9vh">

or if you want more margin, use:

<img src="somefile.svg" style="height: 64vh; margin-top: 18vh; margin-left: 18vh">

and you will have an image on screen good enough for you to do a screenshot -- using CmdShift4 or CmdShift3 on the Mac, for example. Make sure you resize your Chrome window to the maximum allowed on the screen first.

nonopolarity
  • 9,516
  • 25
  • 116
  • 172
11

I have made svgexport using node/npm for this, it is cross-platform and can be as simple as:

svgexport input.svg output.png
Ali Shakiba
  • 261
  • 3
  • 8
7

If you want to do many at once, you can:

mogrify -format png *.svg

There are options to resize etc on the fly, too..

DefenestrationDay
  • 309
  • 1
  • 3
  • 8
6

Yet another method without installing anything. Not in command line though.

  1. Open the .svg file in Safari.
  2. Press alt-command-i to open the inspector.
  3. Right-click on the <svg> tag, select "Capture Screenshot". (Note that you mustn't zoom in the image.)

P.S. To enlarge the .svg image if it's too small, try opening the .svg file in text editor and append 0 to every number except in the meta-attribute. This can be done by a global regex substitution from (\d+) to $10, where $1 is the placeholder for back reference, for example.

Haotian Yang
  • 179
  • 1
  • 1
5

This is what I used:

brew install imagemagick --with-librsvg

Then run the following commands:

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

Hope it helps.

Alan Dong
  • 193
  • 1
  • 6
  • Would be great with an added explanation for what the command does. – P A N Jan 27 '20 at 19:42
  • 1
    Homebrew has removed the ability to provide options so `--with-librsvg` is no longer valid see here https://github.com/Homebrew/homebrew-core/pull/36079 – Andy Jun 14 '21 at 01:05
4

You can also use phantomjs to render the svg. The advantage is that it renders it like a browser would since it's basically a headless WebKit.

Once you download it you need phantomjs (binary) and the rasterizer.js file from the examples folder.

phantomjs examples/rasterize.js Tiger.svg out.png
Stofke
  • 166
  • 1
  • 5
  • 2
    For reference, this can be installed with `brew cask install phantomjs`. In my install, the examples folder was located in the path `/usr/local/Caskroom/phantomjs/2.1.1/phantomjs-2.1.1-macosx/examples/`. – waldyrious Oct 23 '18 at 10:26
  • It's now `brew install --cask phantomjs`. Otherwise it still works great. It doesn't crop the image properly and it's quite slow but it's the only solution that supports embedded fonts. – Timmmm Apr 07 '22 at 13:32
4

Try Apache Batik.

java -jar batik-rasterizer.jar FILES

It also supports batch conversion and has many other useful options.

Behrang
  • 2,032
  • 5
  • 19
  • 26
2

ImageMagick's convert command, using some other parameters, is what did it for me. Here's my batch Bash script solution that divides the task across multiple processes to make use of all your cores! Modify as needed.

batchConvertToSVG.sh (takes number of processes as argument):

end=$(( $1 - 1 ))
for i in `seq 0 $end`;
        do
            echo Spawning helper $i of $end
                ./convertToSvgHelper.sh $i $1 &
        done 

convertToSvgHelper.sh:

n=$1
for file in ./*.svg; do
   filename=${file%.svg}
   echo converting file named $filename
   test $n -eq 0 && convert -format png -resize 74 -background transparent -density 600 $file $filename.png
   n=$((n+1))
   n=$((n%$2))
done
sudo
  • 629
  • 1
  • 6
  • 19
1

You may want to checkout svgexport:

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

svgexport is a simple command-line tool and npm package that I made for exporting svg to png/jpeg. To install svgexport install npm, then run:

npm install -g svgexport
Ali Shakiba
  • 261
  • 3
  • 8
1

I created a function based on @seb 's answer

function svg2png() {
    svgFile=$1;
    width=$2;

    if [[ -z `file ${svgFile} | grep 'Scalable Vector Graphics image'` ]]; then
        echo "file ${svgFile} type is not SVG";
        return 1;
    fi

    echo "file ${svgFile} type is SVG";

    if [[ -z ${width} ]]; then
        echo "width not specified, using width=1024 as default";
        width=1024;
    fi

    pngFile="$(echo ${svgFile} | sed "s/\.[s,S][v,V][g,G]/\.png/")";

    inkscape --export-type png --export-filename ${pngFile} -w ${width} ${svgFile};
}

add this into you .bashrc or .zshrc and execute

source .bashrc
# or
source .zshrc

Usage: svg2png ./Documents/times_clocks.svg 2048

Liu Hao
  • 111
  • 3
1

Okay, so I've found other answers somewhat interesting but not particularly awesome. I wanted to convert every single FontAwesome SVG to a 1920 wide png. But I also wanted to color grade the svg to match my branding. The cool thing about SVGs is that they are XML under the hood.

On macOS I used rsvg-convert command.

Open up the terminal (command + Space then type in terminal.

brew install librsvg

If you don't have Homebrew you'll want to install it. It simplifies installing typical packages available on linux ... but without needing to find the appropriate .pkg files.

Extract the zip or just navigate to the directory wherever you have the folders.

Create a file called, color.css and place it in base directory you're working with.

For example, if you downloaded FontAwesome and extracted it in Downloads you'd cd ~/Downloads/fontawesome-pro-5.15.4-desktop/svgs

or whatever version you moved to.

I use nano -- it's easy for me. You can use any plain text editor though.

For FontAwesome SVGs they basically have an everything color, and for duotone icons they have SVGs with a class of .fa-primary and .fa-secondary.

* { fill: #FAAF40; }
.fa-primary { fill: #FAAF40; }
.fa-secondary { fill: #AD731C; }

Open up the SVG you want to modify and see if it has special classes in it that you want to add color to that deviate from this example.

The first line says everything gets #FAAF40 if not specified; The second line is the same ... so technically it's redundant and can go away but I kept it there for my personal reference. The third line applies #AD731C; just to the fa-secondary CSS class.

find . -type f -name "*.svg" | xargs -I{} rsvg-convert -w 1920 --stylesheet=./color.css {} -o {}.png

This command does all of the magic once you have your color.css file. It looks a bit crazy to those unfamiliar with xargs ... but here's how it works.

find . -type f - name "*.svg" means look in the current directory for any file ending in .svg.

Then pipe that output to the xargs command.

xargs then takes that filename and passes it to the rsvg-convert command with arguments. the {} twice means that the filename is passed in twice. So replace {} in your head with whatever file it's going to fiddle with.

Best of luck!

1

I use this command on my linux. It should work for you as well.

mogrify +antialias -density 2000 -verbose -format png *.svg

I learned that without the "-density" argument, the bitmap would be very pixelized. Change the -density value to match your need.

slhck
  • 223,558
  • 70
  • 607
  • 592
  • 2
    Even with density, the conversion does not generate an image that is as sharp as a vector image. Try Apache Batik instead. – Behrang May 23 '13 at 03:06
0

As commented previously ImageMagick does the trick. I just wanted to add a point for GraphicsMagick, an old fork of ImageMagick that has some improvements (and much less dependency bloat when installed via fink).

0

wkhtmltoimage (from project wkhtmltopdf) did this convert well:

wkhtmltoimage --zoom 2 foo.svg foo.png

ImageMagick renders CJK character as blank on my mac.

georgexsh
  • 129
  • 5
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/813997) – Blackwood Dec 14 '18 at 04:09
  • @Blackwood fine, updated. – georgexsh Dec 14 '18 at 08:11
0

I have started to put together a tool to provide a simplified interface to common actions.

You can convert an SVG to a PNG like this:

$ npm install @mountbuild/mouse -g
$ mouse convert input.svg -o output.png

This will create a new PNG for the SVG.

If nothing else check out the source and see how to write your own script to do this in JavaScript.

Lance
  • 365
  • 2
  • 10
0

Python package cairosvg works best for me.

cairosvg x.svg -o x.png

Install it by
pip3 install cairosvg

ZygD
  • 2,459
  • 12
  • 26
  • 43
orange
  • 15
  • 4
0

You can use svglib:

pip3 install svglib

Code:

from svglib.svglib import svg2rlg
from reportlab.graphics import renderPM

drawing = svg2rlg('input.svg')
renderPM.drawToFile(drawing, 'output.png', fmt='PNG')
wieczorek1990
  • 160
  • 1
  • 5
0

You can perform a batch conversion on an entire folder of SVG files to PNG. I used Inkscape command line interface to produce png files with a width of 80px.

find ~/desktop/toconvert '*.svg' -exec /Applications/Inkscape.app/Contents/Resources/bin/inkscape -z -w 80 -e "{}".png "{}" \;

png will be saved with original name *.png