Search code examples
pythonsvginkscape

Python : Convert svg to png without antialiasing


I'm triying to convert a svg to png in python, but I don't want any compression and antialiasing. I've tried to use inkscape with subprocess but i can't find the arguments to tell inkscape that i don't want any compression and antialisazing.

inkscape_path = "D:/Programmes/bin/inkscape.exe"
dpi_value = 300

result = subprocess.run([inkscape_path, "cleaned.svg", "--export-id=layer1", "--export-ignore-filters", "--export-type=png", "--export-filename=" + "cleaned.png", "--export-dpi=" + str(dpi_value)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

if result.returncode != 0:
    print("Error: " + result.stderr.decode("utf-8"))
else:
    print("PNG file exported successfully.")

I've also tried to do it with wand, but there is still antialiasing despite img.antialisaing = False :

# Load SVG file as an image object
with Image(filename='cleaned.svg') as img:
    # Disable antialiasing
    library.MagickSetOption(img.wand, b'antialias', b'0')
    img.antialias = False
    
    # Convert image format to PNG
    img.format = 'png'
    
    # Save without compression
    img.compression_quality = 100

    # Save to 300 dpi
    img.resolution = (300, 300)
    # Save output file
    img.save(filename='cleaned.png')

In the UI of inkscape in the export process we can specify this, do you know if we can do the same in python, using subprocess or a library ?

enter image description here

Wanted result : enter image description here

Unwanted result : enter image description here


Solution

  • You can set the CSS property shape-rendering:crispEdges to suppress antialiasing. Normally, this would include changing the source SVG files. But for your scenario, you can avoid it.

    librsvg

    If you are able to use librsvg or the commandline version rsvg-convert for the PNG conversion. Since v2.48, it has the ability to load an external style sheet from the command line:

    rsvg-convert -i layer1 -d 300 -p 300 -s crisp.css -o cleaned.png cleaned.svg
    

    crisp.css could be defined like this:

    :root {
      shape-rendering: crispEdges;
    }
    

    There also seem to exist Python bindings for the librsvg library, but I wasn't able to confirm they work with current versions.

    resvg

    A second library to try would be resvg. I haven't much experience yet with its quality, but at least it boasts about the feature support. Anyway, there the shape-rendering hint can be set as a command line parameter:

    rendersvg --export-id=layer1 --dpi=300 --shape-rendering=crispEdges cleaned.svg cleaned.png
    

    The Debian package I used has only v0.8.0 (latest release is 0.29), but for me it worked anyway. See pkgs.org for more choices; Fedora for example is at v0.19, FreeBSD even has v0.28.