194

How do I convert an SVG (containing a few words of latin text and some simple vector graphics) to a PDF on Linux?

I tried Inkscape 0.47 on Ubuntu Lucid, but it moves some sub-graphics randomly, and it makes some lines shorter in the output PDF. So its output is useless, because the graphics looks completely different.

I tried opening the SVG in Google Chrome 16 and printing it to PDF, but it distorts all the colors, and it also removes some elements. (The SVG appears fine on screen, but it's already bad in the print preview and the generated PDF is also bad)

I don't want to rasterize or render the SVG. A solution which converts the SVG to a bitmap image and then creates a PDF with the image embedded is not an answer to my question. (FYI Inscape 0.47 renders the text is a very ugly way, without antialiasing, when rendering to PNG)

Qre there any other options?

2
  • 1
    If you just have a few images to convert you might find it easier to use some of the online converters. I tried CloudConvert and it did a very good job with half the file size of the SVG. Commented Jun 13, 2017 at 17:28
  • I wonder why no one has mentioned Ghostscript? 🤔
    – Foad
    Commented Oct 21 at 18:35

13 Answers 13

199

rsvg-convert did the trick for the SVG I wanted to convert:

$ sudo apt-get install librsvg2-bin
$ rsvg-convert -f pdf -o t.pdf t.svg

rsvg-convert -f pdf doesn't rasterize the SVG, and it embeds and subsets fonts (at least it has embedded the used characters of the Arial font). Sometimes font embedding fails (e.g. for the LMRoman17 font), and the whole font file gets copied to the generated PDF.

Dependencies on Ubuntu Lucid:

  • libcairo.so.2
  • libgobject-2.0.so.0
  • libgthread-2.0.so.0
  • libglib-2.0.so.0
  • librsvg-2.so.2
  • libpthread.so.0
  • libc.so.6

By default, libcairo needs libX11, so rsvg-convert may be hard to install to a headless system.

Note: The man page of rsvg-convert states that the tool always rasterizes, but this isn't true. The manual is simply obsolete. Sometimes your svg generating tool can partially rasterize the svg image, which can also mislead you.

19
  • 4
    That's a lot of dependencies I'm seeing here: cairo, libgphoto, gtk3, libsane...Oh well, if it does the job... Commented Apr 16, 2013 at 15:47
  • 6
    @AyberkÖzgür That's inkscape's fault - when you save an Inkscape project, it will by default save it as a SVG, but the SVG it saves includes a bunch of nonstandard inkscape-specific data that can frequently mess up other programs. You need to export as an SVG rather than just saving as a SVG. Commented Nov 7, 2015 at 23:18
  • 2
    Might save some time searching: On Suse-Systems the package containing rsvg-convert is called rsvg-view. Commented Jan 22, 2016 at 16:14
  • 2
    It worked for me and the quality of pdf is same as svg. Before this was using imagemagick to convert to pdf and the quality was poor especially for svg. Commented May 26, 2016 at 9:08
  • 3
    Worked perfectly for me in macOS. No rasterisation. brew install librsvg then used rsvg-convert -f pdf -o t.pdf t.svg as above.
    – Benjamin R
    Commented Mar 20, 2018 at 4:45
120

This works on Ubuntu Lucid:

$ sudo apt-get install inkscape
$ inkscape t.svg -o t.pdf

The command-line Inkscape invocation above works even in headless mode, without a GUI (DISPLAY=). However, installing Inscape installs lots of dependencies, including X11.

Please note that the exit status of Inskscape is always 0, even if an error occurs -- so watch out for its stderr.

There is also inkscape --shell, suitable for converting many documents in a batch. This avoids the slow Inkscape startup time for each file:

$ (echo t.svg -o t.pdf;
   echo u.svg -o u.pdf) |
  DISPLAY= inkscape --shell

Older versions of Inkscape need the --export-pdf=... flag instead:

$ (echo t.svg --export-pdf=t.pdf;
   echo u.svg --export-pdf=u.pdf) |
  DISPLAY= inkscape --shell

Inkscape is also useful for simplifying an SVG:

$ DISPLAY= inkscape t.svg --export-plain-svg=t.plain.svg
10
  • 2
    Unfortunately this doesn’t seem to work on OS X. Still, nice answer. Commented Nov 26, 2013 at 23:12
  • 3
    The OP specified that Inkscape had rendering bugs; this matches my experience. Commented Oct 22, 2014 at 17:17
  • 3
    On OSX using Homebrew, you can install Inkscape using brew install inkscape these days. The resulting /usr/local/bin/inkscape worked for me without having to run X11.app. Commented Dec 31, 2015 at 22:27
  • 2
    Inkscape can be installed on OS X from the dmg distributed at its own website, and then called from the command line after creating two symbolic links: ln -s ~/Applications/Inkscape.app/Contents/Resources/bin/inkscape ~/bin/inkscape and similarly for inkscape-bin (assuming ~/bin is in your $PATH).
    – 0 _
    Commented Dec 21, 2016 at 13:08
  • 4
    It does work it's just that the inkscape cli currently uses the option --export-filename inkscape.org/doc/inkscape-man.html Commented Oct 22, 2020 at 1:16
17

I have used CairoSVG successfully on OSX and Ubuntu.

pip install cairosvg
cairosvg in.svg -o out.pdf

CairoSVG Documentation

1
  • 2
    There are even python-bindings you can use. Unfortunately I found that this method is rather limited, i.e. a lot of svg features are not supported.
    – bodo
    Commented Mar 12, 2017 at 10:09
15

I'm wondering why it hasn't been mentioned before, but I tested a bunch of different svg->pdf converters and found that the best one is Headless Chrome. It produces the most precise results for me. Before switching to Chrome, I was trying to fight with Inkscape bugs, but many of them are too serious and I can't do much about it (transparency bugs, wrong fonts, etc).

chrome \
  --headless \
  --disable-gpu \
  --no-pdf-header-footer \
  --print-to-pdf=output.pdf \
  input.svg

It needs some tweaks to use custom PDF size (A4 or US Letter is default depending on your system?), but I was able to set custom size after some googling and playing with CSS and SVG attributes (check out this answer on stackoverflow)

Update with example of putting the CSS for the page size in a <style> block in the SVG:

<svg
   width="154.63478"
   height="213.94911"
   ... >

  <style>
    @page {
      size: 154.63478mm 213.94911mm;
      margin: 0;
    }
    svg {
      width: 154.63478mm;
      height: 213.94911mm;
    }
  </style>
  <!-- Your SVG content here -->
</svg>
13
  • 1
    For Red Hat derivates (here Fedora 32) use chromium-browser on the command line ... Commented Aug 27, 2020 at 9:55
  • 1
    Why don't you just share your solution for a custom size? How do I have to modify the command to pass the dimensions? Your linked answer does not tell that... Commented Oct 26, 2020 at 10:20
  • 1
    Perfect. Inkscape and cairosvg don't support underlined text (and probably never will), but chromium does. The option --print-to-pdf-no-header however was changed to --no-pdf-header-footer in newer versions.
    – SimonH
    Commented Jul 9 at 8:49
  • 1
    @Foad I added details to the answer on how to set the page size to match the SVG. Maybe someone should request a feature (command-line flag?) of Chrome headless to do this automatically (since editing the SVG seems like a needless hack). Commented Oct 22 at 3:29
  • 1
    @Fuhrmanator follow-up discussion here.
    – Foad
    Commented Oct 22 at 4:25
10

I get good results from printing from Inkscape (0.47 too) to PDF, and for saving as PDF (but slightly different), but this might depend on the graphic at hand.

An alternative with lower resolution (I did not try any switches to improve it) is

 convert file.svgz file.pdf 

convert is part of the ImageMagick package. Rasterizer is another program:

 rasterizer -m application/pdf file.svgz -d file.pdf 

To find out, which programs which handle svgs are installed on your system, just try

 apropos -s 1 svg

The manpage for these programs should explain, wether the program is useful for converting the svg to pdf.

2
  • 23
    Thank you for your suggestions. FYI convert is not an answer to the original question, because convert rasterizes the SVG to a bitmap image, and the original question was looking for a solution which doesn't do that.
    – pts
    Commented Jan 22, 2012 at 20:15
  • And sometimes you can get the rasterized XML code of the SVG... Commented May 22, 2021 at 21:27
6

https://superuser.com/a/79064/19956 mentions gsvg, part of GhostPDL.

I've tried gsvg ghostpdl-9.06 on Ubuntu Lucid, but it failed for two SVGs generated by Inkscape. One SVG had text in it, the other had only vector graphics. It also failed for simple graphics without Inkscape extensions or clip-path. So I don't consider gsvg a usable SVG-to-PDF converter.

0
5

On Mac OS (considering that you already have brew installed) I do:

$ brew install cairo libffi python3
$ pip3 install cairosvg

$ cairosvg -o blah.pdf ./blah.svg 

Same should work on Linux, but with apt-get instead.

2
  • 1
    This works with pdf output as well. In contrast to svg2pdf and rsvg-convert, this preserves the fonts.
    – oarfish
    Commented Oct 12, 2018 at 14:28
  • This worked for me as well. With inkscape, the pdf may end up being too large. With rsvg-convert, fonts may be lost. With cairosvg the fonts are not lost, and one can rescale to a smaller page size with the -s ... option.
    – pglpm
    Commented Jan 31 at 16:57
5

The answer by @pts doesn't work with recent versions of Inkscape ( 1.0 or newer). To convert an SVG file to PDF:

inkscape --export-type=pdf my_file.svg

This will export it to my_file.pdf.

If you would like to specify a different name for your PDF document, use:

inkscape my_file.svg -o new_name.pdf
2
  • works on macos.
    – Clumsy cat
    Commented Jan 25, 2022 at 13:02
  • You could also add the batch version of this command; as an example: for f in t.svg u.svg; do echo "file-open:$f; export-type:pdf; export-do"; done | inkscape --shell. (Syntax is described in the man page, man inkscape.)
    – David Z
    Commented Aug 10, 2022 at 0:10
3

Awesome solution, Avael Kross (https://superuser.com/users/1057244/avael-kross)!! Headless Chrome worked great for me.

I automated the procedure to remove a header and footer from the output PDF and make it fit to the size of the SVG. I uploaded the shell script to the following gist.

svg2pdf.bash: https://gist.github.com/s417-lama/84bf66de1096c4587e8187092fb41684

Usage:

$ ./svg2pdf.bash input.svg output.pdf
1

Open the svg file with Image Viewer (Also called Eye of Gnome eog) and print it to a PDF file (say image.pdf) and convert that pdf to eps using pdf2ps command. Simple!

Elaborated steps:

  1. Install Image Viewer if not yet done (highly unlikely step if you use gnome)

    sudo apt-get install eog
    
  2. Open svg file with eog and print it to image.pdf file.

  3. (Optional) Remove surrounding whitespace from the pdf file:

    pdfcrop image.pdf
    

    This will generate image-crop.pdf with surrounding whitespace removed.

  4. Convert cropped pdf to eps (use image.pdf directly if you didn't crop the pdf)

    pdf2ps image-crop.pdf image.eps
    

Thats it!

1

Most of the tools mentioned here have problems when displaying SVG 1.1. Therefor, I used the following workaround:

  1. Most browsers seem to be the best viewers for SVG. Firefox and Chrome have full support for SVG 1.1. I just displayed the SVG in the browser.
  2. Then printed the page to PDF, while:
    • fitting the image into the page
    • setting all page borders to 0
    • leaving all headers and footers empty
  3. As you cannot differ from the predefined page sizes, I used pdfcrop afterwards, to get a PDF with the exact dimensions of the SVG.
1

I developed a simple Node.js script that converts SVG files to PDF using Puppeteer. It properly handles foreignObject elements (commonly used by Mermaid CLI's mmdc), scales oversized SVGs, and includes fallback dimension handling.

Usage:

npm install puppeteer
node svg-to-pdf.js input.svg output.pdf
0

This can be done using Inkscape

inkscape input.svg -o output.pdf

You can also crop the svg to its content like this:

inkscape input.svg -o output.pdf --export-area-drawing

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .