svg-silver-age-bg
v1.0.0
Published
Stamp a deterministic silver-age comic-book background (ben-day dots, pinstripes, starburst, panels) onto vectorized line-art SVGs as an isolated, rotatable layer, with render-diff leak detection for holes left by AI vectorizers.
Maintainers
Readme
svg-silver-age-bg
Stamp a deterministic "silver age" comic-book background onto vectorized line-art SVGs — as its own isolated layer, not baked into the artwork.
AI vectorizers (Recraft and friends) turn a redrawn photo into flat black-
and-white line art with a full-canvas white background path and nothing
behind the figures. That's a fine starting point, but it means every image
needs the same manual step in Illustrator: draw in a background treatment,
by hand, one file at a time. This tool automates that step as a batch job —
a classic ben-day dot halftone, a pinstripe tile, or a bold radiating/panel
motif — inserted as a <pattern> fill or a named <g id="silverbg"> group
that a designer can select, recolor, rotate, or mask off without touching
the linework.
Because those same vectorizers often leave white "holes" inside figures (a
gap between an arm and a torso, a stray unfilled patch), a bold background
stamp can show through and read as if it's sitting on the figure instead
of behind it. Before writing a bold style, this tool renders the SVG before
and after stamping and diffs them, isolating the true background with a
border flood-fill so enclosed holes don't get counted as background. If the
stamp leaks through, the bold version is kept as a sibling
<name>-bg-peek-through.svg — you might like it anyway, and can mask the
layer off in Illustrator — while the primary file falls back to a subtle
dot style instead.
Install
# run without installing
npx svg-silver-age-bg art.svg
# or install globally
npm install -g svg-silver-age-bg
svg-silver-age-bg art.svg
# or from a clone
node svg-silver-age-bg.mjs art.svgRequires Node 20+. Zero dependencies. The optional leak check needs
rsvg-convert
on PATH:
brew install librsvgQuick start
svg-silver-age-bg art.svg # random style, in place
svg-silver-age-bg exports/*.svg # every file, independent random style each
svg-silver-age-bg --style stripes art.svg
svg-silver-age-bg --dots-only exports/*.svg # random, but only the four dot shapes
svg-silver-age-bg --list # print the style library and exitRe-running the tool on an already-stamped file is idempotent: it strips the previous pattern or motif layer first, so you can safely re-roll a file as many times as you like.
The target SVG
svg-silver-age-bg stamps onto a full-canvas white background path —
the shape a vectorizer emits behind the artwork, of the form
<path fill="#fff" d="M0 0h<W>v<H>H0z"/>. If a file doesn't have one, the
tool errors out clearly rather than guessing:
art.svg: no full-canvas white background path found (expected
<path fill="#fff" d="M0 0h<W>v<H>H0z"/>). svg-silver-age-bg targets
vectorizer output like Recraft's — run it before other tools reshape the
background, or check this file actually has a solid white backing path.This is why the tool is meant to run right after vectorizing (e.g. as a step after Recraft vectorize, or the companion gemini-vectorize pipeline), before anything else reshapes or removes that background path.
Style library
| style | kind | look |
|---|---|---|
| circle | dot | ben-day dot halftone, round dots |
| oval | dot | ben-day dot halftone, elongated dots |
| triangle | dot | ben-day dot halftone, triangular dots |
| square | dot | ben-day dot halftone, square dots |
| stripes | tile | 45-degree pinstripes |
| starburst | motif | bold rays radiating from a center point |
| corner-burst | motif | sweeping rays from the top-right corner |
| panels | motif | diagonal comic-panel bands |
Dot and tile styles become a <pattern id="benday"> fill swapped onto the
background path. Motif styles are inserted as a <g id="silverbg"> layer
directly above the background path (below the artwork) — because rays or
panel bands need to be cut off by nothing but the canvas edge, not tiled.
With no --style, each file gets an independent random pick from the full
8-style library. --dots-only narrows the random pool to the four dot
shapes (handy if you've already been burned by a leak and just want
something safe).
Leak detection
Bold styles (stripes, starburst, corner-burst, panels) cover large,
solid areas — exactly what shows through a hole in the artwork. Dot styles
don't get this treatment: at ben-day scale, a dot or two peeking through a
gap doesn't read as a mistake.
Before committing to a bold stamp, the tool:
- renders the pre-stamp SVG to a raster with
rsvg-convert, - flood-fills from the four canvas borders across connected white pixels — that flood-filled region is the "true" background,
- renders the stamped SVG and diffs it against the pre-stamp render,
- flags a leak if more than 0.5% of the canvas changed outside the flood-filled region — i.e., the pattern shows up somewhere flood-fill never reached, which can only be an enclosed gap inside the artwork.
On a flag, the bold stamp is saved as <name>-bg-peek-through.svg next to
the original, and the primary file gets re-stamped with a random dot style
instead so you always get a safe default:
art.svg: starburst may show through holes in the artwork -> kept as
art-bg-peek-through.svg; primary stamped with circle dots insteadThis can be a false positive. An enclosed white gap between someone's arm and their torso ("arms akimbo") looks exactly like a hole to a border-flood-fill — there's no way to tell "artwork gap" from "vectorizer mistake" from pixels alone. That's why the bold file is kept, not discarded: open both, and if the leak looks fine (or even good) in context, just use the peek-through file instead of the dot fallback.
If rsvg-convert isn't on PATH, the check is skipped automatically with a
note, and the bold stamp is kept as primary (same as --no-leak-check).
Options
| flag | meaning |
|---|---|
| --style <name> | pin a style instead of picking randomly (see the table above) |
| --dots-only | random pool limited to the four dot shapes |
| --no-fallback | on a leak, keep the bold stamp as primary — warn, but don't write a sibling file |
| --no-leak-check | skip the render-diff entirely (also auto-skipped if rsvg-convert is missing) |
| --list | print the style library and exit |
| --help | print usage |
Multiple files are processed independently — one file's leak or error doesn't stop the rest. The process exits non-zero only on a hard error (missing file, no background path found, etc).
Illustrator workflow
Open the stamped SVG in Illustrator: dot/tile styles land as a single path
with a pattern fill (select it, Object > Pattern > Edit Pattern to nudge
scale/rotation, or just rotate the filled path itself); motif styles land as
a plain silverbg group of shapes you can select, recolor, or rotate like
any other layer. Either way, the linework above it is untouched.
Companions
- svg-color-rinse — snap the
dozen near-blacks and near-whites a vectorizer leaves behind into clean
#000000/#ffffffanchors, with optional svgo minification. Run this first if your source SVG hasn't been rinsed yet. - gemini-vectorize — batch photo → Gemini redraw → Recraft vectorize → svg-color-rinse, the pipeline that typically produces the SVGs this tool stamps.
Development
npm test # node --test against the fixture in test/fixtures/The leak-detection and fallback tests only run if rsvg-convert is found on
PATH; otherwise they're skipped rather than failing.
License
MIT
