How to convert SVG to PNG or JPEG in Python?

13,153

Solution 1

pyvips supports SVG load. It's free, fast, needs little memory, and works on macOS, Windows and Linux.

You can use it like this:

import pyvips

image = pyvips.Image.new_from_file("something.svg", dpi=300)
image.write_to_file("x.png")

The default DPI is 72, which might be a little low, but you can set any DPI you like. You can write to JPG instead in the obvious way.

You can also load by the pixel dimensions you want like this:

import pyvips

image = pyvips.Image.thumbnail("something.svg", 200, height=300)
image.write_to_file("x.png")

That will render the SVG to fit within a 200 x 300 pixel box. The docs introduce all the options.

The pyvips SVG loader has some nice properties:

  • It uses librsvg for the actual rendering, so the PNG will have high-quality anti-aliased edges.
  • It's much faster than systems like ImageMagick, which simply shell out to inkscape for rendering.
  • It supports progressive rendering. Large images (more than a few thousand pixels a side) are rendered in sections, keeping memory use under control, even for very large images.
  • It supports streaming, so you can render an SVG directly to a huge Deep Zoom pyramid (for example) without needing any intermediate storage.
  • It supports input from memory areas, strings and pipes as well as files.

Rendering from strings can be handy, eg.:

import pyvips

x = pyvips.Image.svgload_buffer(b"""
<svg viewBox="0 0 200 200">
  <circle r="100" cx="100" cy="100" fill="#900"/>
</svg>
""")

x.write_to_file("x.png")

Solution 2

For converting svg to png, there are 2 ways I can think of:

1. Here is lib which can do what you need: https://cairosvg.org/documentation/

$ pip3 install cairosvg

python3 code:

cairosvg.svg2png(url="/path/to/input.svg", write_to="/tmp/output.png")

Have used it on linux (debian 9+ and ubuntu 18+) and MacOS. It works as expect for large files about 1MB svg. Example: world map. Lib also allow to export pdf file.

Tip: cairosvg provide scaling up of png output image as default size looks blurry after working with vector graphics svg :) . I couldn't get DPI option working for me.

2. There is another method to do same by using browser to open svg file and take screenshot using Selenium webdriver either with Firefox or other browser. You can save screenshot as png.

One can use Pillow to convert png to jpeg: Convert png to jpeg using Pillow

Solution 3

On Windows, you get errors like libgobject-2.0-0.dll, libvips-42.dll, etc. not found when trying to import pyvips. To get pyvips working on Windows, do the following:

In code do this:

import os

# The bin folder has the DLLs
os.environ['path'] += r';C:\Path\ToYour\VIPsFolder\bin'

import pyvips

image = pyvips.Image.thumbnail("test.svg", 200)
image.write_to_file("test.png")

I recommend using pyvips over cairosvg. From my tests it's much faster than cairosvg, especially for large SVGs. You need to something similar to the above to get cairosvg working on Windows anyway.

Solution 4

I looked several methods, including cairo (which I could not make it work on Windows), svglib+reportlab (dpi cannot be changed) and even inkscape (from command line).

At the end this is the best method I found. I tested it on python 3.7.

def convert(method, svg_file, png_file, resolution = 72):
    from wand.api import library
    import wand.color
    import wand.image

    with open(svg_file, "r") as svg_file:
        with wand.image.Image() as image:
            with wand.color.Color('transparent') as background_color:
                library.MagickSetBackgroundColor(image.wand, 
                                                 background_color.resource) 
            svg_blob = svg_file.read().encode('utf-8')
            image.read(blob=svg_blob, resolution = resolution)
            png_image = image.make_blob("png32")

    with open(png_file, "wb") as out:
        out.write(png_image)

I had to install the wand package (using pip) and then ImageMagick for Windows (http://docs.wand-py.org/en/latest/guide/install.html#install-imagemagick-on-windows).

Share:
13,153

Related videos on Youtube

hkm
Author by

hkm

Updated on June 27, 2022

Comments

  • hkm
    hkm almost 2 years

    I'm using svgwrite and generating svg-files, how do I convert them to PNG or JPEG?

    • domochevski
      domochevski almost 6 years
      @qräbnö Well since svgwrite does not seem to handle svg to png conversion, then ... yes you need another library. Another example for the same question can also be found here: stackoverflow.com/questions/2932408/…
  • Mark Kortink
    Mark Kortink almost 3 years
    This solution requires you to install libvips as per libvips.github.io/libvips/install.html. If you already have InkScape or such like you may not want another editor. Libvips is pretty low level and techie.
  • Mark Kortink
    Mark Kortink almost 3 years
    After installing libvips still get error = "cannot load library 'libgobject-2.0-0.dll': error 0x7e. Additionally, ctypes.util.find_library() did not manage to locate a library called 'libgobject-2.0-0.dll'".
  • jcupitt
    jcupitt almost 3 years
    Did you find the pyvips windows install notes? libvips.github.io/pyvips/README.html#non-conda-install ... if you're still having problems, please open an issue on the pyvips tracker and I'll try to help github.com/libvips/pyvips/issues/new
  • jcupitt
    jcupitt almost 3 years
    The useful answer stackoverflow.com/a/67429047/894763 below explains the windows install process.
  • Mark Kortink
    Mark Kortink almost 3 years
    Tried the useful answer below and it works.