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
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.
- 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.
- 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. - 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'tofill='currentColor';- match near-whites with a regex such as
#F[EF]F[0-9A-F]{3}plus#FFFFFF, replace withfill='var(--m-fill)'; - accent hex to
fill='var(--m-accent)'; - fail if any other hex fill remains.
- replace the width/height attributes on the svg element with
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.