Sunday, March 3, 2013

Export layers from svg files to png using xslt and inkscape

If you have svg files and you want to export all but one layer, or only some specific layers to png files using the command line (e.g. in an automated batch job or script), you can not do this with Inkscape out of the box. There is no parameter to export only one layer or to export all but one layer or anything similar. Because svg files are actually xml files, you can use xslt to strip out the layers you do not want to export.

Prerequisites

  • You need inkscape and an xslt transformation tool installed.
  • For Windows you can use msxsl
  • For Linux you can use xsltproc.
  • Of course, you need an svg file with multiple layers created with inkscape. (Inkscape uses the <g> tag to create layers and the layer name that you can see and modify in Inkscape is specified in the "inkscape:label" attribute).

Exporting all but one layer

To export all but a certain layer, you can use this xslt template. You just have to change the "inkscape:label" from 'Layer 2' to whatever layer name you want.

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:svg="http://www.w3.org/2000/svg"
    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
    >
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="svg:g[@inkscape:label='Layer 2']"/>
</xsl:stylesheet>

Just copy this text into a text-file and save it (preferable with the file extension ".xsl" or ".xslt").
Then, from the command-line, do the following:

msxsl Example.svg YourXsltFile.xslt -o YourNewExample.svg
C:\Program Files (x86)\Inkscape.com YourNewExample.svg --export-png=YourNewExample.png
(Use "xsltproc -o YourNewExample.svg YourXsltFile.xslt Example.svg" instead of msxsl for Linux).

Exporting certain layers

When you want to export just a number of layers, it's better to use this template for the xslt file:
<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:svg="http://www.w3.org/2000/svg"
    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
    >
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="svg:g"/>

    <xsl:template match="svg:g[@inkscape:label='Background']|svg:g[@inkscape:label='Layer 2']">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

8 comments:

  1. What is this directory "Inkscape.com"

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. I couldn't use parameters or variables in "label=$param"-part.
    I was doing like this:
    cmd : msxsl prodoln_1ots_1.svg svglayers2png.xsl -o new_section1.svg layer='14'

    and in .xsl: label='$layer_num',or label=$layer_num.

    it tells me "You can't use parameters here"

    P.S. Sorry for spam.

    ReplyDelete
  4. Great information you have posted in this blogs. it will help every one.

    ReplyDelete
  5. the following script provides for easy command-line options to do just that:
    https://github.com/berteh/svg-objects-export/

    objects (or layers) to export can be selected on their ID (with wildcards) as well as using full xpath for the more tech savy.

    ReplyDelete
  6. Hi Daniel, thanks for the XSLT stylesheet. I've adapted it a bit for my situation, by having a global which each layer label is compared against. I can then apply it using xmlstarlet:

    xmlstarlet tr select-layers.xsl -s layer=0-initial shared-memory.svg > shared-memory-0-initial.svg

    (I've also tried to get it to set style="display:inline" on any layers it does keep, since I often save the source file with some layers hidden.)

    I'm doing this in a makefile that builds a Beamer presentation.

    Edmund

    ReplyDelete