Video to ASCII

A p5.js sketch that turns a live webcam feed into moving ASCII art, right in the browser.

2022-02-15
javascript p5.js creative-coding webcam graphics

A small creative-coding project: point your webcam at yourself and watch the picture redraw as text, dozens of times a second. It started from The Coding Train's ASCII image coding challenge and runs entirely in your browser. No video ever leaves your machine.

View Source Code on GitHub


Try It

Press Start camera and allow access when your browser asks. On a phone, the front camera works best.

How It Works

The trick is to throw away almost all of the video. The webcam is captured at just 64 x 48 pixels, and each of those pixels becomes one character.

  1. Every frame, read the pixel buffer from the tiny capture.
  2. Average each pixel's red, green, and blue values into a single brightness from 0 to 255.
  3. Map that brightness onto a "density" string ordered from the heaviest-looking glyph to the lightest, so the brightest pixels get the heaviest glyphs:
const density = "Ñ@#W$9876543210?!abc;:+=-,._                    ";
  1. Join the characters into rows and drop the result into a <pre> block.

Because the page is white text on black, dense glyphs like Ñ and @ put the most ink on screen and read as the bright parts of the image, while the run of spaces at the end of the string leaves the darkest areas empty.

Technologies Used: JavaScript, p5.js, the browser MediaDevices (webcam) API

Lessons Learned

  • Resolution is the whole look. A higher-resolution capture sounds better but just becomes an unreadable wall of tiny text. At 64 x 48 your face is still recognizable while every character stays visible.
  • The density string is the art direction. Its trailing spaces aren't a typo: they decide how much of the frame reads as empty background. A shorter ramp with fewer steps gives a flatter, more poster-like result.
  • Browsers guard the camera. getUserMedia only works on secure (HTTPS) pages, and every visitor has to grant permission, which is why the demo above waits for a click instead of asking the moment the page loads.

Comments & Feedback

Project Links