Turn a photo into a self-typing, monochrome ASCII portrait SVG that animates inside a GitHub profile README. No JavaScript, no third-party stats service, no token.
GitHub strips <script> from READMEs and sanitizes almost all inline CSS. But it does render SVGs embedded via <img>, and it runs their SMIL animations. So all the motion has to live inside the SVG file itself. The README just places it.
# the magic repo: name it exactly your GitHub username
gh repo create <your-username> --public --clone
cd <your-username>
pip install pillow numpy opencv-python-headless rembg onnxruntime
First run downloads a ~176 MB u2net.onnx model for background removal. One time only.
Four stages. Each one exists because skipping it makes the output worse.
rembg isolates the subject. Everything outside the matte gets forced to pure white, which maps to the blank end of the character ramp. Without this the background fills with @ and % and drowns the portrait.
Contrast-limited adaptive histogram equalization. Regular autocontrast works globally and leaves a flatly-lit face as one uniform mid-tone. CLAHE boosts contrast per-tile, so the face gets real highlights and shadows.
clipLimit around 2.2 to 3.0 is the useful range. Higher amplifies skin texture into noise. Run a bilateral filter first to smooth skin while keeping edges.
RAMP = " .`:-=+*cs#%@" # bright/sparse -> dark/dense
# ^ leading space clears the background to nothing
Monospace characters are roughly twice as tall as wide, so the row count is cols * (h/w) * 0.48.
Two choices that matter: