July 9th, 2007 @ 22:43

This afternoon, while making some posters for the French Free Software World Meetings (RMLL), I was willing to get a high resolution PNG version of the Compiz SVG logo. I fired up Inkscape, created a landscape A3 document loaded the original logo file, scaled it and ran the export tool to get a 300 dpi A3 PNG. 20 minutes later it was still running… While it was still running I took my laptop and wrote a quick script using python cairo and librsvg bindings. 5 minutes later (yeah, reading documentations/googling for examples takes a while), I ran it and got my high resolution PNG. I cleaned it up this evening, here is the end result script =)

Usage : svntopng [–width WIDTH] [–height HEIGHT] [-o OUTPUTFILE] SOURCEFILE

#!/usr/bin/python
 
'''svgtopng - SVG to PNG converter
Copyright (c) 2007 Guillaume Seguin <guillaume@segu.in>
Licensed under GNU GPLv2'''
 
import cairo
import rsvg
from sys import argv
from os.path import exists
import getopt
 
def usage ():
    print "Usage : %s [--width WIDTH] [--height HEIGHT] [-o OUTPUTFILE] FILE" % argv[0]
    raise SystemExit
 
if __name__ == "__main__":
    try:
        opts, args = getopt.getopt (argv[1:], 'o:h',
                                    ['width=', 'height=', 'output=', 'help'])
    except getopt.GetoptError:
        usage ()
    output = None
    width = None
    height = None
    for o, a in opts:
            if o in ('-o', '--output'):
                output = str (a)
            elif o == '--width':
                width = int (a)
            elif o == '--height':
                height = int (a)
            elif o in ('-h', '--help'):
                usage ()
    if len (args) == 0:
        usage ()
    file = args[0]
 
    if not exists (file):
        usage ()
 
    svg = rsvg.Handle (file = file)
 
    if not output:
        if file[-4:] == ".svg":
            file = file[:-4]
        output = "%s.png" % file
        base = "%s%d.png"
        i = 1
        while exists (output):
            output = base % (file, i)
            i += 1
 
    if width == 0 and height == 0:
        width = svg.props.width
        height = svg.props.width
    elif width != 0:
        ratio = float (width) / svg.props.width
        height = int (ratio * svg.props.height)
    elif height != 0:
        ratio = float (height) / svg.props.height
        width = int (ratio * svg.props.width)
 
    surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, width, height)
    cr = cairo.Context (surface)
 
    wscale = float (width) / svg.props.width
    hscale = float (height) / svg.props.height
 
    cr.scale (wscale, hscale)
 
    svg.render_cairo (cr)
 
    surface.write_to_png (output)