578

I have a SVG file that has a defined size of 16x16. When I use ImageMagick's convert program to convert it into a PNG, then I get a 16x16 pixel PNG which is way too small:

convert test.svg test.png

I need to specify the pixel size of the output PNG. -size parameter seems to be ignored, -scale parameter scales the PNG after it has been converted to PNG. The best result up to now I got by using the -density parameter:

convert -density 1200 test.svg test.png

But I'm not satisfied, because I want to specify the output size in pixels without doing math to calculate the density value. So I want to do something like this:

convert -setTheOutputSizeOfThePng 1024x1024 test.svg test.png

So what is the magic parameter I have to use here?

fmw42
  • 46,825
  • 10
  • 62
  • 80
kayahr
  • 20,913
  • 29
  • 99
  • 147
  • 7
    e.g. `-size 1024x1024` is working fine, what is your imagemagick version? – Dejan Marjanović Mar 29 '12 at 18:14
  • ImageMagick version is 6.6.9.7. Maybe it depends on the SVG? My SVG defines a fixed size of 16x16 in the header and all coordinates are absolute values and not percent values or something like this. – kayahr Mar 30 '12 at 13:34
  • 1
    http://superuser.com/questions/516095/bake-an-svg-image-into-a-png-at-a-given-resolution – Dave Jarvis Sep 25 '13 at 01:48
  • 2
    ImageMagick-6.9.0-Q16. convert -resize 1024x1024 foo.svg foo.png works fine. – Jichao Mar 10 '15 at 18:59
  • 12
    @Jichao `-resize` just stretches the converted image, with poor quality results. – Elist Dec 11 '15 at 10:37
  • 12
    `convert -size 1024x1024 test.svg test.png` works fine with ImageMagick 7.0.7-0 Q16 (current version in Chocolatey repo for Windows). Just make sure that `-size` appears before the input filename, else a 16x16 picture will be upscaled to give a blurry result. – Futal Sep 08 '17 at 22:12
  • FYI ImageMagick is pretty awful when it comes to SVG conversions. For example, it's text positioning is [broken](https://stackoverflow.com/questions/53417436/imagemagick-svg-to-png-conversion-screws-up-text-position). I found that a better option was to use a Node module that leverages PhantomJS, like [svg2png](https://github.com/domenic/svg2png). – Yarin Nov 23 '18 at 15:16
  • @Futal you should post your comment as an answer. It may not have been available when OP posted this but in 2022 it's better than the existing answers imo – adamdport Dec 21 '22 at 16:43

20 Answers20

702

I haven't been able to get good results from ImageMagick in this instance, but Inkscape does a nice job of scaling an SVG on Linux and Windows:

# Inkscape v1.0+
inkscape -w 1024 -h 1024 input.svg -o output.png
# Inkscape older than v1.0
inkscape -z -w 1024 -h 1024 input.svg -e output.png

Note that you can omit one of the width/height parameters to have the other parameter scaled automatically based on the input image dimensions.

Here's the result of scaling a 16x16 SVG to a 200x200 PNG using this command:

enter image description here

enter image description here

Shovalt
  • 6,407
  • 2
  • 36
  • 51
808sound
  • 7,866
  • 1
  • 15
  • 13
  • 21
    +1 as far as imagemagick is concerned. There seem to be problem with the SVG engine. In most cases I wasn't able to get accurate results with it. Inkscape, OTOH, works perfectly fine. – Glutanimate Mar 18 '13 at 15:36
  • 19
    I think Inkscape is the single most impressive example of OSS after Linux itself. Thanks for the tip! – kim3er Jul 08 '13 at 18:40
  • 10
    Works nicely on OSX too. – Jonas Granvik Sep 24 '13 at 20:08
  • 1
    Great. My problem wasn't changing the size, but that ImageMagick turned transparent areas in the SVG into white areas in the PNG. Inkscape preserves the transparency correctly. – Rörd Oct 26 '13 at 15:28
  • Another positive thing is that Inkscape is way faster than imagemagick's convert. – scai Nov 15 '13 at 07:39
  • 2
    You can use -d 1200 to also set the DPI. – wieczorek1990 Mar 03 '14 at 13:03
  • 17
    On OSX, with Inkscape installed for X11, it worked for me using: `/Applications/Inkscape.app/Contents/Resources/bin/inkscape -z -e test.png -w 1024 -h 1024 test.svg` – chmullig Mar 14 '14 at 00:26
  • Note: Inkscape does not seem to have an option to respect the aspect ratio when exporting. If you need that, try using `rsvg` (or `rsvg-convert`) instead. – Denilson Sá Maia Sep 09 '14 at 23:43
  • 16
    @Rörd To keep background transparent with ImageMagick, use `-background none` command line option. – John Jan 11 '15 at 22:45
  • 1
    Inkscape is badass. On mac setup an alias `alias inkscape="/Applications/Inkscape.app/Contents/Resources/bin/inkscape"` – Miguel Mota Jun 03 '15 at 19:16
  • This works wonderfully on OSX. I installed inkscape with homebrew cask (http://caskroom.io/) and the command worked out of the box. – lxe Jul 03 '15 at 18:42
  • 1
    I was able to install this on OSX using homebrew with `brew install homebrew/x11/inkscape` – danielson317 Jul 13 '15 at 14:10
  • 3
    @DenilsonSá : If you specify only the width OR the height, Inkscape will keep aspect ratio. – Skippy le Grand Gourou Jul 30 '15 at 10:09
  • 1
    Also worth mentioning, to set white background with inkscape instead of default transparency : `-b white`. – Skippy le Grand Gourou Sep 29 '15 at 10:09
  • Nice solution. The only issue is that it shows a GUI prompt for every image I want to convert. What's the right way to suppress that? edit: Never mind, my command was wrong. Properly written it does not produce any outputs of any kind. – Andy Ibanez Feb 06 '17 at 21:56
  • 1
    Recent versions on OS X change the current working directory. I assume there are good reasons for this but it means you need to use absolute paths for the file arguments. – Vanessa Phipps Mar 28 '17 at 19:55
  • Building using this method doesn't have this problem: https://inkscape.org/en/download/mac-os/#alternative_install_0.92 Sounds like the issue is whether it's installed in `/usr/local/bin/inkscape` as a binary, or as a script that changes `CWD` and `exec`s the binary in `/Applications`. – Vanessa Phipps Mar 28 '17 at 20:26
  • 4
    Batch convert in one line using bash and Inkscape: If you want to convert all the svg files in a directory to a specific size (30x30): `for file in *.svg; do inkscape -z -e "${file/.svg/.png}" -w 30 -h 30 $file; done` – Daniel Bower May 30 '17 at 12:25
  • Inkscape just wrecks my SVG. It's like it's ignoring transform declarations, but also printing some stuff black which doesn't have a background colour when rendered correctly. – Hakanai Jun 22 '17 at 14:12
  • @Trejkaz I've never seen that happen before, so I'm not sure what could be the problem. One of the above comments recommends using `-background none` to keep the transparency. I also looked around a bit and found that there is [an Inkscape bug](https://bugs.launchpad.net/inkscape/+bug/1430716) which you could be running into... – 808sound Jun 22 '17 at 22:57
  • That bug might account for the black backgrounds on some of the elements, for sure. The text not being transformed is a bit terrible too, but svgexport is doing that as well, so at the moment my best idea for converting is to use phantomjs. – Hakanai Jun 24 '17 at 04:01
  • 4
    Just to add a note: You can use just single parameter between width and height and the other parameter will scale automatically. For example you may just use -w 1024 and -h will scale automatically. – PallavBakshi Jan 17 '18 at 06:43
  • 1
    By the way, what this does is the following: Using Inkscape, without a GUI, export to `test.png`, with `1024` pixels in width and `1024` pixels in height, from `test.svg`. – caw Feb 11 '20 at 22:44
  • 2
    I just installed Inkscape 1.0.1 for Ubuntu and it has a "-o" option as a an alternative to "export-filename". Haven't checked Mac yet but I imagine it is the same, thus avoiding the difference in the OS's. – crowmagnumb Oct 02 '20 at 02:40
  • 1
    I also noticied this correctly handled a gradient background for my icon where magick convert did not – BossmanT Oct 27 '20 at 16:23
  • 1
    On Inkscape 1.0 (4035a4fb49, 2020-05-01) - Win10 - export-filename requires `=` or as @crowmagnumb said use `-o` – ATutorMe Jan 14 '21 at 06:02
  • I edited to add what I see as some more common use cases more directly first since I just keep coming back here, feel free to revert if you feel otherwise, cheers. – Ciro Santilli OurBigBook.com Feb 11 '21 at 10:21
  • ImageMagick by now has no more issues rendering SVG, is better documented, makes it easy to export at specific resolution or target height/width – qubodup Jun 02 '21 at 14:43
  • With imagemagick `convert img.svg -background none -size 1024x1024 img.png` works perfectly – João Pimentel Ferreira Apr 09 '22 at 12:10
  • @qubodup imagemagick (newest version at time of writing) still completely fails with nested `` and `` references. Even inkscape only drew half of the image file I have to png. It renders fine in various browsers and passes validation so the file is fine. I ended up having to install pip: `cairosvg` was the only one able to successfully rasterise the complex svg I have – Hashbrown Sep 01 '22 at 04:40
193

Try svgexport:

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

svgexport is a simple cross-platform command line tool that I have made for exporting svg files to jpg and png, see here for more options. To install svgexport install npm, then run:

npm install svgexport -g

Edit: If you find an issue with the library, please submit it on GitHub, thanks!

Ali Shakiba
  • 20,549
  • 18
  • 61
  • 88
  • 7
    svgexport worked great for me. Output matches browser rendering much more closely than ImageMagick. – t9mike Mar 25 '15 at 01:00
  • 1
    this worked well for me as well. Real time saver compared to doing it manually in a GUI tool. Quite difficult to find a GUI app on mac in the cheaper range anyway that handles SVG well – Erik Engheim Jun 02 '15 at 12:54
  • svgexport didn't do anything for me on OSX, just ended up with blank image – Phil Ryan Jul 17 '15 at 01:02
  • 4
    Works great, but produces a huge image. Using optipng, I was able to compress my text logo down from 3 megabytes to ~20kB. – miek Aug 07 '15 at 12:19
  • Inkscape did not work well on MacOS but this one did the job, Good job ! – Mathias Asberg Feb 01 '17 at 15:28
  • @Timmmm Can you please [submit an issue](https://github.com/shakiba/svgexport/issues/new) on GitHub with an example? – Ali Shakiba Mar 10 '17 at 01:18
  • Actually I think it may work; turned out my SVG relied on implicit image dimensions which are (I think) part of SVG 2. Chrome renders them fine, but I guess they've started implementing SVG 2. – Timmmm Mar 10 '17 at 13:49
  • @AliShakiba Can you please guide how can I use it on Windows. Even better, if you can tell me how can I use your code in my Visual Studio 2015 application? – ubaabd Jun 03 '17 at 07:00
  • @ubaabd Can you please open an issue on github? It is difficult to discuss it in comments. – Ali Shakiba Jun 05 '17 at 06:00
  • @AliShakiba Just did that. The issue is open on github. – ubaabd Jun 09 '17 at 21:19
  • 4
    evgexport creates HUGE png files depending on the size. Recommend svg2png which also uses PhantomJS for export, but creates much smaller images. – Aaron_H Jul 27 '17 at 03:59
  • Agree with @Aaron_H, I tried both and [svg2png](https://github.com/domenic/svg2png) does this better. svgexport produced a huge 308 KB file while svg2png produced same quality file at 25 KB. – Yarin Nov 23 '18 at 15:24
  • `svg2png` doesn't rotate line markers (such as arrow heads) correctly for me and the PNG produced was bigger than the one from `svgexport`, which renders the SVG exactly as in the browser (while Inkscape didn't load the remote font). So +1 from me for `svgexport` as the only tool who accomplished what I was looking for. – Kaspar Etter Apr 13 '20 at 18:48
  • Exactly what I've been looking for for a long time. Great! Thank you! – Mig Jul 24 '20 at 13:49
143

This is not perfect but it does the job.

convert -density 1200 -resize 200x200 source.svg target.png

Basically it increases the DPI high enough (just use an educated/safe guess) that resizing is done with adequate quality. I was trying to find a proper solution to this but after a while decided this was good enough for my current need.

Note: Use 200x200! to force the given resolution

Dheeraj Bhaskar
  • 18,633
  • 9
  • 63
  • 66
Hardev
  • 10,851
  • 2
  • 17
  • 17
  • 7
    Opacity and shadows lost in my case. – jiyinyiyong Jan 07 '14 at 14:05
  • 2
    I don't have complex svg so this worked for me. `-resize 200%` did not work and I had to specify size in pixels. – jozxyqk Mar 26 '14 at 10:34
  • 30
    @jiyinyiyong To keep background transparent with ImageMagick, use `-background none` command line option. To keep image ratio, you also could specify only one dimension like `-resize 200` for width or `-resize x200` for height. See: http://www.imagemagick.org/script/command-line-processing.php#geometry for exhaustive _ImageMagick geometry_ options. – John Jan 11 '15 at 22:45
  • doesn't work for me either. The result is all blurry. – mbonnin Jul 07 '15 at 23:47
  • (this applies to linux, may apply to windows) if you turn -verbose on IM then it would appear that IM itself uses inkscape to create an intermediate eps file. therefore i would suggest using inkscape directly as suggested by @808sound – northern-bradley Aug 09 '17 at 18:40
  • 1
    And the batch version is ```for file in ./*.svg; do convert -density 1200 -background none -resize 200x200 $file `basename $file .svg`.png; done``` – polkovnikov.ph Nov 08 '18 at 15:36
  • Be careful: it approximates curved paths with segments https://i.stack.imgur.com/foL91.png – Pavel Jun 07 '19 at 16:35
  • Convert first to PNG (since background white does not work), then take the PNG and convert to PNG or JPG (with white background). – Avatar May 13 '22 at 10:14
85

Inkscape doesn't seem to work when svg units are not px (e.g. cm). I got a blank image. Maybe, it could be fixed by twiddling the dpi, but it was too troublesome.

Svgexport is a node.js program and so not generally useful.

Imagemagick's convert works ok with:

 convert -background none -size 1024x1024 infile.svg outfile.png

If you use -resize, the image is fuzzy and the file is much larger.

BEST

rsvg-convert -w 1024 -h 1024 infile.svg -o outfile.png

It is fastest, has the fewest dependencies, and the output is about 30% smaller than convert. Install librsvg2-bin to get it:

sudo apt install -y librsvg2-bin

There does not appear to be a man page but you can type:

rsvg-convert --help

to get some assistance. Simple is good.

masterxilo
  • 2,503
  • 1
  • 30
  • 35
  • 4
    This is easily the best answer (I don't know why twenty different answers give the same imagemagick response); it preserves colors and shadows and doesn't mangle anything. However, to match the imagemagick resize behavior (in particular, WxH means scale image to fit in a box of that size, preserving aspect ratio), the `-a` parameter should be used with rsvg. – Mahmoud Al-Qudsi Jan 05 '17 at 23:45
  • 1
    This mangled my images, all sorts of weird artifacts. inkscape did a better job. – elegant dice Mar 22 '17 at 13:58
  • 1
    Be warned, `brew install rsvg` on OSX installs a million things - GDK, OpenSSL, Python, etc. – Timmmm May 16 '17 at 13:35
  • 7
    FYI, the current install command is `brew install librsvg` and the conversion command is `rsvg-convert`. – waldyrious Oct 23 '18 at 09:56
  • 4
    I found librsvg (or `rsvg-convert` in case of Arch) to give the best and most consistent results when converting complicated svgs to png. Follow up with `optipng` to reduce output file size. – maktel May 27 '20 at 14:55
  • 3
    In Ubuntu: `sudo apt install librsvg2-bin; rsvg-convert input.svg -o output.png` – MestreLion Sep 21 '20 at 07:25
  • I had success with rsvg-convert 2.4.20 on Windows. – SzieberthAdam Oct 09 '20 at 08:19
  • 1
    After doing some performance testing across various ways of converting SVGs to PNGs, `rsvg-convert` is also the fastest I have found by far (much faster than Puppeteer with Chromium, Playwright with Chromium, ImageMagick, Inkscape and SVG.NET at least) – George Helyar Oct 04 '22 at 11:33
  • Simple is the best, this worked so smoothly compared to all the answers above it:) – thisisashwani Apr 14 '23 at 12:10
60

If you are on MacOS X and having problems with Imagemagick's convert, you might try reinstalling it with RSVG lib. Using HomeBrew:

brew remove imagemagick
brew install imagemagick --with-librsvg

Verify that it's delegating correctly:

$ convert -version
Version: ImageMagick 6.8.9-8 Q16 x86_64 2014-12-17 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
Features: DPC Modules
Delegates: bzlib cairo fontconfig freetype jng jpeg lcms ltdl lzma png rsvg tiff xml zlib

It should display rsvg.

Jose Alban
  • 7,286
  • 2
  • 34
  • 19
  • Didn't work for me. Specifically I ran `convert ic_comment_48px.svg -size 30x30 ic_comment_30px.png` and the output image is 48 x 48. Made sure that imagemagick is delegating to rsvg as you've explained. – Shane Creighton-Young Mar 14 '17 at 20:39
  • 1
    Worked perfectly for me - the default `convert` did convert svg to png, but the results were hopeless; after reinstalling, they're perfect. Also, conversion is significantly faster. – ssc May 01 '17 at 21:34
  • 1
    This worked me on Mac OSX. I don't find the new conversion faster, but much much more accurate. I highly recommend all Mac OSX users give this a try. – ABCD Jun 27 '17 at 10:11
  • 1
    This should be the accepted answer, oh well. Thank you, worked like a charm, and I never would have known to take these steps otherwise – sdailey Aug 31 '18 at 17:07
  • This answer still helps a lot, also unter OSX high sierra. – Mathias Oct 11 '18 at 08:47
  • 19
    On mojave i get `invalid option: --with-librsvg` – zaitsman Mar 27 '19 at 03:20
  • 4
    @zaitsman Probably too late, but... The argument option has changed, try with `--with-rsvg`. And I think it needs the `librsvg2-bin` package to be installed. See https://gist.github.com/maxivak/1476f7e979879da9f75371a86d5627b5 – NickGnd Mar 11 '21 at 14:41
  • ImageMagick utilizes [inkscape](http://www.inkscape.org/) if it's in your execution path, otherwise [RSVG](http://developer.gnome.org/rsvg/). If neither are available, ImageMagick reverts to its internal SVG renderer. The default resolution is 96 DPI. Use [-size](http://www.imagemagick.org/script/command-line-options.php#size) command line option to specify the maximum width and height. If you want to render a very large SVG and you trust the source, enable this option: `-define svg:xml-parse-huge=true`. – ikaerom May 24 '22 at 07:26
23

After following the steps in Jose Alban's answer, I was able to get ImageMagick to work just fine using the following command:

convert -density 1536 -background none -resize 100x100 input.svg output-100.png

The number 1536 comes from a ballpark estimate of density, see this answer for more information.

João Pimentel Ferreira
  • 14,289
  • 10
  • 80
  • 109
Ian
  • 11,280
  • 3
  • 36
  • 58
19

In ImageMagick, one gets a better SVG rendering if one uses Inkscape or RSVG with ImageMagick than its own internal MSVG/XML rendered. RSVG is a delegate that needs to be installed with ImageMagick. If Inkscape is installed on the system, ImageMagick will use it automatically. I use Inkscape in ImageMagick below.

There is no "magic" parameter that will do what you want.

But, one can compute very simply the exact density needed to render the output.

Here is a small 50x50 button when rendered at the default density of 96:

convert button.svg button1.png


enter image description here

Suppose we want the output to be 500. The input is 50 at default density of 96 (older versions of Inkscape may be using 92). So you can compute the needed density in proportion to the ratios of the dimensions and the densities.

512/50 = X/96
X = 96*512/50 = 983


convert -density 983 button.svg button2.png


enter image description here

In ImageMagick 7, you can do the computation in-line as follows:

magick -density "%[fx:96*512/50]" button.svg button3.png

or

in_size=50
in_density=96
out_size=512

magick -density "%[fx:$in_density*$out_size/$in_size]" button.svg button3.png
fmw42
  • 46,825
  • 10
  • 62
  • 80
  • 2
    +1 for the magical fx expression which avoids a separate command, or use of a calculator. As a side note, if you run `identify -format "%x x %y (%w x %h) file.svg`, you will also get the width and height for the default density in the output (which you need for $in_size in the formula)! – Till Kuhn Aug 28 '20 at 10:05
  • you can do it even in 1 line https://stackoverflow.com/a/66901038/1597158 – Torsten B Apr 01 '21 at 08:33
  • Thanks! It works like a charm! and if you add the option `-background none` you'll also have a .png with transparent background! – Mattia Ducci Jan 12 '22 at 13:12
18

In order to rescale the image, the option -density should be used. As far as I know the standard density is 72 and maps the size 1:1. If you want the output png to be twice as big as the original svg, set the density to 72*2=144:

convert -density 144 source.svg target.png
waldyrious
  • 3,683
  • 4
  • 33
  • 41
17

On macOS using brew, using librsvg directly works well

brew install librsvg
rsvg-convert test.svg -o test.png

Many options are available via rsvg-convert --help

mloughran
  • 11,415
  • 7
  • 28
  • 22
11

For simple SVG to PNG conversion I found cairosvg (https://cairosvg.org/) performs better than ImageMagick. Steps for install and running on all SVG files in your directory.

pip3 install cairosvg

Open a python shell in the directory which contains your .svg files and run:

import os
import cairosvg

for file in os.listdir('.'):
    name = file.split('.svg')[0]
    cairosvg.svg2png(url=name+'.svg',write_to=name+'.png') 

This will also ensure you don't overwrite your original .svg files, but will keep the same name. You can then move all your .png files to another directory with:

$ mv *.png [new directory]
MestreLion
  • 12,698
  • 8
  • 66
  • 57
edank
  • 191
  • 1
  • 2
  • 7
  • crashed for me on windows 10: import cairocffi as cairo File "c:\program files (x86)\python35-32\lib\site-packages\cairocffi\__init__.py", line 39, in cairo = dlopen(ffi, 'cairo', 'cairo-2', 'cairo-gobject-2', 'cairo.so.2') File "c:\program files (x86)\python35-32\lib\site-packages\cairocffi\__init__.py", line 36, in dlopen raise OSError("dlopen() failed to load a library: %s" % ' / '.join(names)) OSError: dlopen() failed to load a library: cairo / cairo-2 / cairo-gobject-2 / cairo.so.2 – Pete Lomax Mar 31 '19 at 04:26
  • 1
    Nice, `cairosvg` on Ubuntu-19.04 did the job for me. – fhgd Dec 09 '19 at 15:35
  • I just wanted to write: What an excellent solution! The first PNGs looked great, but others didn't. Instead I have to write: It completely depends on the SVG which solution offers the best quality. – Regis May Feb 11 '21 at 14:07
  • `cairosvg` worked for me on Ubuntu 20.04 instances (WSL and Gcloud free tier VM). From a base image, I had to `sudo apt install python3-pip`, followed by the `pip3 install cairosvg` command above. From there, I was able to use the command line executable from `~/.local/bin/cairosvg`. – Marc Oct 14 '22 at 17:19
8

why don't you give a try to inkscape command line, this is my bat file to convert all svg in this dir to png:

FOR %%x IN (*.svg) DO C:\Ink\App\Inkscape\inkscape.exe %%x -z --export-dpi=500 --export-area-drawing --export-png="%%~nx.png"

ampecs
  • 81
  • 1
  • 2
8

This is what worked for me and would be the easiest to run.

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

This will loop all the files in your current folder and sub folder and look for .svg files and will convert it to png with transparent background.

Make sure you have installed the librsvg and rename util

brew install librsvg
brew install rename
Shivam
  • 652
  • 12
  • 14
6

Transparent background, exported at target height/size using ImageMagick 7:

magick -background none -size x1080 in.svg out.png

One-liner mass converter:

for i in *svg; do magick -background none -size x1080 "$i" "${i%svg}png"; done
qubodup
  • 8,687
  • 5
  • 37
  • 45
  • I'm surprised this answer is so low. Some of the other approaches drew my complicated SVG incorrectly, but this worked perfectly. – Archr Jan 13 '22 at 13:24
  • I had to use `convert`, but otherwise it worked perfectly (`convert -background none -size x1080 in.svg out.png`). – Michael Johansen Jan 31 '22 at 13:44
5

I came to this post - but I just wanted to do the conversion by batch and quick without the usage of any parameters (due to several files with different sizes).

rsvg drawing.svg drawing.png

For me the requirements were probably a bit easier than for the original author. (Wanted to use SVGs in MS PowerPoint, but it doesn't allow)

Qohelet
  • 1,459
  • 4
  • 24
  • 41
5

Without librsvg, you may get a black png/jpeg image. We have to install librsvg to convert svg file with imagemagick.

Ubuntu

 sudo apt-get install imagemagick librsvg
 convert -density 1200 test.svg test.png

MacOS

 brew install imagemagick librsvg
 convert -density 1200 test.svg test.png

Community
  • 1
  • 1
TLbiz
  • 487
  • 8
  • 7
4

One thing that just bit me was setting the -density AFTER the input file name. That didn't work. Moving it to the first option in convert (before anything else) made it work (for me, YMMV, etc).

Nick
  • 2,803
  • 1
  • 39
  • 59
2

On Linux with Inkscape 1.0 to convert from svg to png need to use

inkscape -w 1024 -h 1024 input.svg --export-file output.png

not

inkscape -w 1024 -h 1024 input.svg --export-filename output.png
sbkm
  • 107
  • 5
1

I've solved this issue through changing the width and height attributes of the <svg> tag to match my intended output size and then converting it using ImageMagick. Works like a charm.

Here's my Python code, a function that will return the JPG file's content:

import gzip, re, os
from ynlib.files import ReadFromFile, WriteToFile
from ynlib.system import Execute
from xml.dom.minidom import parse, parseString


def SVGToJPGInMemory(svgPath, newWidth, backgroundColor):

    tempPath = os.path.join(self.rootFolder, 'data')
    fileNameRoot = 'temp_' + str(image.getID())

    if svgPath.lower().endswith('svgz'):
        svg = gzip.open(svgPath, 'rb').read()
    else:
        svg = ReadFromFile(svgPath)

    xmldoc = parseString(svg)

    width = float(xmldoc.getElementsByTagName("svg")[0].attributes['width'].value.split('px')[0])
    height = float(xmldoc.getElementsByTagName("svg")[0].attributes['height'].value.split('px')[0])

    newHeight = int(newWidth / width * height) 

    xmldoc.getElementsByTagName("svg")[0].attributes['width'].value = '%spx' % newWidth
    xmldoc.getElementsByTagName("svg")[0].attributes['height'].value = '%spx' % newHeight

    WriteToFile(os.path.join(tempPath, fileNameRoot + '.svg'), xmldoc.toxml())
    Execute('convert -background "%s" %s %s' % (backgroundColor, os.path.join(tempPath, fileNameRoot + '.svg'), os.path.join(tempPath, fileNameRoot + '.jpg')))

    jpg = open(os.path.join(tempPath, fileNameRoot + '.jpg'), 'rb').read()

    os.remove(os.path.join(tempPath, fileNameRoot + '.jpg'))
    os.remove(os.path.join(tempPath, fileNameRoot + '.svg'))

    return jpg
Yanone
  • 165
  • 10
1

The top answer by @808sound did not work for me. I wanted to resize Kenney.nl UI Pack

and got Kenney UI Pack messed up

So instead I opened up Inkscape, then went to File, Export as PNG fileand a GUI box popped up that allowed me to set the exact dimensions I needed.

Version on Ubuntu 16.04 Linux: Inkscape 0.91 (September 2016)

(This image is from Kenney.nl's asset packs by the way)

James L.
  • 12,893
  • 4
  • 49
  • 60
0

I was getting "low poly" curves using the general approach of increasing the density. So I decided to dig a little deeper and solve that problem as it seemed to be a side effect of this approach and I think it has to do with the original density or dpi.

We have seen 72 in this answer and 96 in this answer being suggested as the default density of an image, but which one? what if mine is different?

ImageMagick has a way to sort that out:

identify -verbose test.svg

this will put out a lot of metadata about the image file, including:

Image:
  Filename: test.svg
  Format: SVG (Scalable Vector Graphics)
  Mime type: image/svg+xml
  Class: ...
  Geometry: ...
  Resolution: 37.79x37.79
  Print size: ...
  Units: PixelsPerCentimeter
  # and a whole lot MORE ...

for a more concise query you can try:

identify -format "%x x %y %U" test.svg
=> 37.789999999999999147 x 37.789999999999999147 PixelsPerCentimeter

as suggested by this forum post and modified with this documentation

Now we know the current density of the image but may need to convert it to the correct units for conversion or mogrifying (PixelsPerInch or dpi)

this is a simple calculations of PixelsPerCentimeter x 2.54

37.789999999999999147 x 2.54 = 95.9866 ~> 96

if you prefer a chart or online calculator for this you can try https://www.pixelto.net/cm-to-px-converter.

now that we have the right original density converted to dpi, the rest of the logic stated in the above answers falls into place and the svg file can be scaled to a better "resolution" by multiplying the original density.

the original density was far too pixelated as a png for me, so in my case 5x the original density or -density 480 was good enough for me. Remember that this resizes the image as well and you will need to adjust for that when using / implementing the image as compared to the original svg.

NOTE: I did try the Inkscape approaches as well and also had the pixelation problem, but had already seen an improvement with the density approach so I decided to dig into that deeper. The output of the Inkscape attempt however gave me the idea, which you can also use for determining the dpi, but that is a lot to install just to get something you can already get with ImageMagick

Area 0:0:20.75:17 exported to 21 x 17 pixels (96 dpi)
SMAG
  • 652
  • 6
  • 12