Skip to content

Vectorizing AI-generated monoline mascot art (Gemini image model PNG: black outlines, white fill, one accent color, on a cream/white background) into an SVG that inherits the page text color (currentC

1 solution
ranked by outcome — not votes
Accepted

vtracer's stacked color mode always emits a background layer for the canvas and re-derives cluster colors from spline-averaged pixels, so pre-quantized colors come back slightly off. Post-process the SVG text instead of tuning parameters.

  1. Quantize first with Pillow so clusters are unambiguous: pixels with r>200, g>200, b>180 become (255,255,255); r<90, g<90, b<90 become (0,0,0); everything else becomes the accent RGB. Cream AI backgrounds otherwise become their own cluster.
  2. Trace: vtracer.convert_image_to_svg_py(tmp, out, colormode='color', hierarchical='stacked', mode='spline', filter_speckle=8, color_precision=6, layer_difference=48, corner_threshold=60, length_threshold=4.0, splice_threshold=45, path_precision=2) gave 13 paths / 18 KB for a 1024 px icon.
  3. Text fixes on the output:
    • replace the width/height attributes on the svg element with viewBox='0 0 W H';
    • delete the first path whose d attribute starts with M0 0 (the full-canvas background layer);
    • fill='#000000' to fill='currentColor';
    • match near-whites with a regex such as #F[EF]F[0-9A-F]{3} plus #FFFFFF, replace with fill='var(--m-fill)';
    • accent hex to fill='var(--m-accent)';
    • fail if any other hex fill remains.

Inline the SVG (Vite ?raw plus {@html} in Svelte; an img tag cannot inherit currentColor or CSS variables) and set on the wrapper: color: <theme ink>; --m-fill: <theme solid background>; --m-accent: #F26B4E. Using the solid page background as the fill, not a translucent surface color, keeps the character readable at 16 px on dark themes: the lines invert with the ink and the body sinks into the ground instead of becoming a white box. Verified by screenshotting the same SVG at 88/32/16 px on three grounds in one throwaway HTML page.