ascii-shape-renderer
v1.0.0
Published
Shape-aware ASCII renderer using 6D shape vectors and contrast enhancement
Maintainers
Readme
ASCII Shape Renderer
📖 This library implements the techniques from Alex Harri's brilliant blog post
"ASCII characters are not pixels" — If you want to understand why this works, read his post. It's excellent and covers everything in depth with interactive demos.

Live Demo | Video Demo | All Examples
How It Works
From Alex Harri's post:
"Most ASCII renderers map each pixel's brightness to a character... but this ignores the shape of each character."
Instead, this library:
- Captures character shapes using 6 sampling circles in a staggered grid
- Matches shapes via k-d tree lookup in 6D space
- Enhances contrast to sharpen edges and prevent "staircasing"
The result: characters follow contours instead of creating blocky pixels.
Features
- Sharp edges via shape matching (not brightness mapping)
- Color modes: none, foreground, background, or both
- Video & webcam support with Web Workers
- Single script tag — no build step required
Quick Start
Browser
<script src="https://unpkg.com/ascii-shape-renderer"></script>
<pre id="output"></pre>
<script>
AsciiRenderer.image('photo.jpg', '#output', { colorMode: 'fg' });
</script>Video
<script>
AsciiRenderer.video('video.mp4', '#output', { colorMode: 'both' });
</script>Webcam
<script>
AsciiRenderer.webcam('#output', { colorMode: 'fg' });
</script>npm
npm install ascii-shape-rendererimport { AsciiRenderer } from 'ascii-shape-renderer';
const renderer = new AsciiRenderer({ colorMode: 'fg' });
const ascii = renderer.render(imageData);Node.js
Works in Node.js with the canvas package:
npm install ascii-shape-renderer canvasconst { createCanvas, loadImage } = require('canvas');
const { AsciiRenderer } = require('ascii-shape-renderer');
const renderer = new AsciiRenderer({ colorMode: 'fg' });
const img = await loadImage('photo.jpg');
const canvas = createCanvas(img.width, img.height);
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
const ascii = renderer.render(ctx.getImageData(0, 0, img.width, img.height));
console.log(ascii);Options
| Option | Default | Description |
|--------|---------|-------------|
| colorMode | 'none' | 'none', 'fg', 'bg', or 'both' |
| globalContrastExponent | 2 | Sharpens all boundaries |
| directionalContrastExponent | 3 | Prevents staircasing at edges |
| cellWidth / cellHeight | 10 / 16 | Cell size in source pixels |
Credits
This is an implementation of Alex Harri's ASCII rendering technique. All the clever ideas — shape vectors, contrast enhancement, k-d tree lookups — come from his post.
Sample video: Big Buck Bunny © Blender Foundation | CC BY 3.0
License
MIT
