Automating Inkscape







Ted Gould
Libregraphics @ SCALE 23x
March 8, 2026

_

WHOAMI

  • Original Developers of Inkscape
    • Forked of Sodipodi with Bryce, Mental and Nathan
    • Developed extensions system
    • Presented at SCALE 5x
  • Currently: Inkscape PLC
  • Professionally: Building a GPU security startup
Inkscape Draw Freely

Think differently about graphics

  • Traditionally: Every graphic design was a manual process in a GUI.
  • Today: Graphics need to go everywhere and be flexible.
  • Use Text: Scalable Vector Graphics (SVG) are fundamentally XML.
  • Solution: Programmatic manipulation of XML + The Inkscape Rendering Engine.
Inkscape Draw Freely

Architectural Evolution: 0.92 vs. 1.x

  • Legacy (0.92.x): Required --without-gui flag.
  • Modern (1.x): Headless by default for exports/queries.
  • POSIX Alignment: Dropped -f (file) flag; input is now a positional argument.
  • Consolidation: Unified export structure under --export-filename.
Inkscape Draw Freely

From "Verbs" to "Actions"

  • Verbs (Legacy): Deeply coupled to GUI; required display servers (X11).
  • Actions (Modern): Atomic, headless operations interacting with the DOM.
  • Chaining: Multiple operations in one command via semicolons.
  • Syntax: --actions="[id]; [id]" replaces limited GUI-dependent hooks.
Verbs were essentially menu-click simulators. Actions are true API calls. Use `inkscape --action-list` to see them all.
Inkscape Draw Freely

The "Hello World" of Automation

  • Input: A basic SVG file (e.g., logo.svg).
  • Goal: Export a clean PNG from a vector source.

inkscape --export-type="png" --export-filename="output.png" input.svg
This is the most common entry point. Note that the output filename is explicit; if omitted, Inkscape defaults to the input name with the new extension or last export.
Inkscape Draw Freely

Speed Optimization: Shell Mode

  • Problem: Restarting Inkscape for 1,000 files is slow
  • Solution: --shell mode a REPL
  • Benefits
    • Engine remains resident in RAM
    • Scripts pipe commands continuously into one process
Inkscape Draw Freely

History: OpenStreetMap Osmarender

  • Pipeline: OSM XML XSLT SVG PNG.
  • The Role of Inkscape
    • Used as a distributed "printer" for tiles.
    • Unique support for text-on-path labels and SVG filters.
Inkscape Draw Freely

Metatiling & Slicing (The OSM Way)

  • Input: A massive map SVG (map.svg) representing a 4x4 tile grid.
  • Goal: Slice one specific 256x256 tile from a larger canvas.


inkscape --export-area=0:0:256:256 \
         --export-width=256 \
         --export-height=256 \
         map.svg

Inkscape Draw Freely

Software: Multi-Resolution Icons

  • Input: A single high-detail master logo SVG.
  • Goal: Generate a standard 32px icon and a high-DPI 64px version.

inkscape --export-id="Logo" --export-width=32 \
   --export-filename="icon_32.png" master.svg;
inkscape --export-id="Logo" --export-width=64 \
   --export-filename="icon_64.png" master.svg

NOTE: You probably want several size 'ranges' with different detail

Inkscape Draw Freely

Game Dev: Procedural Spritesheets (1/2)

  • Input: One SVG with frames on layers named walk1, walk2, etc.
  • Output
    • Export a specific frame by its internal XML ID.
    • Combine into an animation with ImageMagick
Inkscape Draw Freely

Game Dev: Procedural Spritesheets (2/2)

IDS=$(inkscape --query-all character.svg \
  | awk -F',' '$1 ~ /^walk/ {print $1}')
for ID in $IDS; do
  inkscape \
    --export-id="$ID" \
    --export-id-only \
    --export-type=png \
    --export-filename="frames/${ID}.png" \
    character.svg
done
# Stitch into spritesheet with ImageMagick
convert frames/walk*.png +append walk_sheet.png
Inkscape Draw Freely

Data Injection (1/2)

  • Input: A template SVG with placeholders like %VAR_name%.
  • Output: Batch-produce personalized ID cards or conference badges.
Inkscape Draw Freely

Data Injection (2/2)


while IFS=, read -r name title org; do
  sed -e "s/%VAR_name%/$name/g" \
      -e "s/%VAR_title%/$title/g" \
      -e "s/%VAR_org%/$org/g" \
      badge_template.svg > "badge_${name}.svg"
  inkscape --export-type=png \
      --export-filename="badge_${name}.png" \
      "badge_${name}.svg"
done < attendees.csv

Inkscape Draw Freely

Scientific Poster

  • Input: A poster template with a placeholder for a plot.
  • Goal: Embed a new data plot into a vector layout headlessly.


inkscape \
  --actions="select-by-id:plot_area; file-open:plot.png; export-do" \
  figure.svg

Inkscape Draw Freely

Hardware: Robotic Pen Plotters

  • Input: Generative art with thousands of overlapping lines.
  • Goal: "Clean" the SVG by converting all text and objects to paths.


inkscape \
  --actions="select-all; object-to-path; selection-ungroup; export-do" \
  -o clean.svg input.svg

Inkscape Draw Freely

Inkstich

  • Input: A simple logo SVG.
  • Goal: Add hardware "Trim" commands to specific paths before exporting.

inkstitch --extension=object_commands --trim=true --id=path45 \
  < logo.svg > logo_with_trims.svg

The Ink/Stitch CLI allows for "Stitch Plans" to be generated headlessly for quality control in manufacturing.

Inkscape Draw Freely

Fabrication: CNC & Laser Cutting

  • Input: A CAD design for a mechanical part.
  • Goal: Offset the path (outset) to compensate for the laser beam width (kerf).

inkscape --actions="select-all; object-to-path; path-outset; export-do" \
   -o cut_ready.svg part.svg

Inkscape Draw Freely

Security in Headless Environments

  • Risk: Malicious XML External Entities (XXE) in user-provided SVGs.
  • Mitigation: Use a pre-processor like svg-hush.

svg-hush < untrusted.svg > sanitized.svg
inkscape --export-type="png" sanitized.svg

Inkscape Draw Freely

Summary

  • The Engine: Inkscape is now a CLI powerhouse, not just a drawing tool.
  • Growing: Now with actions and the shell automation is stable and GUI-free.
  • Takeaway: Your SVGs can effectively be used for programmatic consumption.
Inkscape Draw Freely

Thank you!
Questions?

Inkscape Draw Freely