Friday, February 18, 2011

Exporting slices from Inkscape, part 2

I previously wrote about how to export slices from an Inkscape file, using a bash script. Here's a better script, using Python, which doesn't require you to give your slices any special label.

The new process is as follows:

  • First, draw your image as usual.
  • Then, add a layer that will hold the slices; name it slices (this is important). Set the layer's opacity to about 50% to be able to see what you're doing. Enable the grid, and make sure it is set to pixels: you want your slices to align with pixel boundaries.
  • Draw your slice rectangles onto the slices layer, aligned to the grid. Ensure that the rectangles have no border; the fill is irrelevant (I use red).
  • Right-click a slice, and choose Object Properties. Change Id field to the name of the eventual PNG file, without the extension. The area defined by a rectangle named foo will be saved to foo.png. Repeat this for all slices.
  • Hide the slices layer. If you forget this, the script will print a warning.
  • Save your image. Let's say you called it layout.svg.
  • Run the script as follows:
    ./ layout.svg
    You should see each of your slices being exported to a PNG file in the same directory.

Here's the code for the script. Save this to a file and make it executable.

#!/usr/bin/env python

import sys
import os
from xml.dom import minidom

if len(sys.argv) < 2:
    print 'Usage:  %s filename.svg' % sys.argv[0]
input_file = sys.argv[1]

dom = minidom.parse(input_file)
groups = dom.getElementsByTagName('g')
for group in groups:
    if group.getAttribute('inkscape:groupmode') == 'layer' and group.getAttribute('inkscape:label') == 'slices':
        if 'display:none' not in group.getAttribute('style'):
            print 'Warning: slices layer might still be visible'
        for element in group.getElementsByTagName('rect'):
            export_id = element.getAttribute('id')
            filename = '%s.png' % export_id
            print 'Exporting %s...' % filename
            os.system('inkscape --export-id="%s" --export-png="%s" --file="%s"' % (export_id, filename, input_file))
    print 'No layer named "slices" found; not exporting anything'


Marc Paradise said...

Thanks for the post; can you think of any way to do this and export not as png, but as individual SVG documents?

Thomas ten Cate said...

I think replacing --export-png by --export-plain-svg should go a long way towards that. But maybe that simply makes it adjust the boundaries, without clipping or discarding (partly) invisible objects... dunno. said...

Heathrow Airport Taxi
- Specializing in Heathrow & Gatwick Taxi Transfer Services. Book Online now, Professional 24 hour service to any major city across the UK. Call us International - +442084221515.