Skip to content

Instantly share code, notes, and snippets.

@dunkfordyce
Created November 23, 2011 13:58
Show Gist options
  • Save dunkfordyce/1388722 to your computer and use it in GitHub Desktop.
Save dunkfordyce/1388722 to your computer and use it in GitHub Desktop.
render svg to seperate files
import sys
import cairo
import rsvg
from ctypes import *
c_rsvg = CDLL('librsvg-2.so.2')
if len(sys.argv) < 2:
print "usage: filename.svg [css-selector [css-selector [...]]]"
print "if css-selector isnt passed then all top level groups will be exported"
sys.exit(1)
fn = sys.argv[1]
selector = ','.join(sys.argv[2:]) if len(sys.argv) > 2 else '>svg|g'
from lxml import etree
from lxml.cssselect import CSSSelector
sel = CSSSelector(selector, namespaces={'svg':'http://www.w3.org/2000/svg'})
svg = etree.parse(open(fn)).getroot()
groups = sel(svg)
class RsvgPositionData(Structure):
_fields_ = [("x", c_int),
("y", c_int)]
class RsvgDimensionData(Structure):
_fields_ = [("width", c_int),
("height", c_int),
("em",c_double),
("ex",c_double)]
# regular rsvg handle to draw the svg for cairo
handle_py = rsvg.Handle(None, etree.tostring(svg))
error = ''
# ctypes rsvg handle so we can get element sizes/positions
handle = c_rsvg.rsvg_handle_new_from_file(fn, error)
for group in groups:
if 'id' not in group.attrib:
print "skipping element because it has no id"
continue
gid = '#'+group.attrib['id']
out_fn = group.attrib['id'] + '.png'
# grab the posisiton and size of the element
p = RsvgPositionData()
d = RsvgDimensionData()
c_rsvg.rsvg_handle_get_position_sub(handle, byref(p), gid)
c_rsvg.rsvg_handle_get_dimensions_sub(handle, byref(d), gid)
print gid, '-->', out_fn #, p.x, p.y, d.width, d.height, d.em, d.ex
# create a new surface the correct size ( +1 for a reason im not sure of... )
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, d.width+1, d.height+1)
ctx = cairo.Context(surface)
# "undo" the translation of the element
ctx.translate(-p.x, -p.y)
# draw the element at effectivly 0, 0
handle_py.render_cairo(ctx, id=gid)
surface.write_to_png(out_fn)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment