# Ascii Art

> Generate and decode real ASCII, braille, ANSI, and 3D text art with the ditherlab CLI/MCP — from images, from geometry you describe (scene DSL), from 3D scenes and extruded text, with auto-tuned settings — apply and teach named themes, and draw by hand only with measured technique and exemplars. Use whenever the user asks for ASCII art, text art, a banner or logo for a CLI/README/MOTD, braille art, ANSI color art, dithering, a pixel/retro look, a spinning/3D terminal piece, converting an image, video, or webcam to text, an animated text GIF, identifying or decoding pasted art, or "make it look like <style>" — even if they only say "draw X in the terminal" or "make it look retro". Also use for flowcharts, sequence diagrams, state machines, timelines, mindmaps, and architecture diagrams in text (Mermaid in, box drawing out), bar/column/ spark charts from data, box-drawing tables, directory/outline trees, boxed notes, FIGlet banners, and for checking or repairing any hand-drawn text art (`ditherlab lint`). Stays

- Skill: `daronthedragon/ascii-art` (Agent Skill, multi-file: 18 files)
- Install (CLI): `npx skillmds@latest add daronthedragon/ascii-art`
- Raw SKILL.md: https://api.skillmd.com/api/skills/daronthedragon/ascii-art/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Design & Media
- License: MIT
- Author: daronthedragon (https://skillmd.com/u/daronthedragon)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/daronthedragon/ascii-art

---


# ASCII art with ditherlab

Hand-typed art fails predictably: guessed densities, ignored 1:2 cell aspect,
no light direction. ditherlab dithers real pixels into characters (so the art
is right by construction), renders 3D primitives, decodes art back to images,
and carries **themes** — named looks with settings and hand-drawing rules that
you can apply and extend. Use the tool for pictures; use the references for
craft; save what works.

## Persistence

ACTIVE EVERY RESPONSE once triggered. Still active if unsure. Off only when
the user says "stop ascii-art" or "normal mode".

## Setup

`ditherlab --help`. Not on PATH? `node <clone>/bin/ditherlab.js`, or clone
https://github.com/daronthedragon/ditherlab (zero deps, Node 18+, `npm link`).
MCP instead of shell: `ditherlab agents mcp <client>` prints the config for
any MCP client (cursor, windsurf, cline, roo, vscode, zed, gemini, codex,
claude — for Claude: `claude mcp add ditherlab -- node <clone>/src/mcp.js`);
`ditherlab agents install <name|all>` writes these instructions where other
agents read them (AGENTS.md, .cursor/rules, .github/copilot-instructions.md, …)
→ tools `render_text_art render_3d draw_scene auto_tune banner figlet
diagram table tree box lint_art gallery decode_art render_art_image
dither_image list_themes save_theme info`, plus
resources `ditherlab://references/*`, `ditherlab://themes`, `ditherlab://gallery`,
`ditherlab://figlet-fonts`. PNG, JPEG (baseline + progressive), GIF, BMP,
PGM/PPM decode with zero dependencies; ffmpeg on PATH adds WebP/TIFF and video.

## Procedure

Run every time, in order. Stop at the first step that resolves the task.

1. **Style named or implied?** ("blueprint", "Game Boy", "sketch", "for my
   README"): `ditherlab themes`. Matching theme → use `--theme <name>` in
   every command below. No match → compose settings from the references,
   render, and after the user approves, `ditherlab theme save <name> …`
   with a `--use-when` naming their phrase (references/themes.md).
2. **Art from an image** (photo, screenshot, logo): `ditherlab inspect
   photo.jpg` first when unsure — it reports tones, colorfulness,
   transparency, edge density, and the width that fits 24/40 rows, with
   suggested flags. Then pick mode from the table and run — or let the tool
   pick: `ditherlab auto photo.jpg --mode braille
   -w 70` searches ~100 settings, scores each by how much structure survives,
   and prints the best art plus its command. Paste output verbatim. Add
   `--save-theme <name> --use-when "…"` when the result is worth keeping.
3. **Banner text**: classic FIGlet look (READMEs, CLI headers, MOTDs):
   `ditherlab figlet "ship it" -f slant` (`--list` shows the 15 bundled
   fonts — standard slant small big banner shadow script mini block lean
   digital bubble term smslant smscript; `-f path.flf` loads any FIGlet
   font; `--width 80 --center` wraps/centers). Pixel-font banner:
   `ditherlab text "SHIP IT"` (`--style block|shadow|half|braille|quadrant`,
   `--frame round --title …`); lowercase / a real typeface look: `--font
   mono` (8×16 glyphs; pair with `--style half` or `braille` to keep it
   short). Never hand-type block letters or FIGlet letters.
4. **3D / spinning / "donut" / 3D logo**: `ditherlab 3d torus --rx 0.9
   --ry 0.6 -w 70 --mode braille`; `--spin --frames 24 -o spin.gif`
   animates; `--mode shape` sketches; `ditherlab 3d --text "GO" --ry 0.4`
   extrudes letters; `--extrude logo.png` extrudes a bitmap; `--scene
   "sphere s=1.1; box op=subtract s=0.8 ry=0.6; torus y=-1.4 s=0.5"`
   composes objects with CSG (`op=union|subtract|intersect|smooth`,
   `x= y= z= rx= ry= rz= s=`). Other forms: script pixels (PGM) then encode
   — the ten-line sphere in references/3d-and-shading.md.
5. **"Something cool / abstract / a poster / a screensaver"**: `ditherlab
   gen attractor --seed 42 -w 70` (also plant, maze --solve, truchet,
   plasma, automaton --rule 110, rose) — seeded, reproducible; offer two
   seeds. For images that must look hand-made: `--mode flow` (strokes wrap
   the forms), `hatch` (engraving), `stipple` (dots). references/generative.md.
6. **Subject with no image** ("draw a house", "a rocket", "a face"): do not
   type from imagination. Describe it as geometry with the scene DSL and
   render: `ditherlab draw scene.txt --mode braille -w 60` (primitives:
   `rect circle ellipse line poly text`, units 0–100, `fill=` `stroke=`
   `shade=sphere|cylinder`; `ditherlab draw --help-dsl` and `--example
   house|rocket|face|cup|planet` show working scenes). If a real image of the
   subject exists, use it instead. For something tiny (≤ 8 rows), check
   `ditherlab gallery <name|tag>` for an exemplar and adapt it. Last resort:
   hand-draw following references/freehand.md and the theme's `freehand`
   rules, and say it is hand-drawn.
7. **Motion on demand** ("animate it", "zoom into it", "matrix reveal", a
   README hero): `ditherlab fx photo.jpg --preset crash-zoom -o out.gif` —
   camera moves (ken-burns, crash-zoom, dolly-in, pull-back, vertigo,
   handheld, keyframe paths), reveals (typewriter, scan, dissolve, matrix),
   layers (glitch, rain, snow, stars, fireworks), `--crt` phosphor exports;
   `.cast` for terminals, `.gif` for READMEs (references/motion.md).
   MCP: `animate_art`.
8. **Video, webcam, GIF → animation**: `ditherlab play clip.mp4 -w 80 --mode
   braille --fps 12 -o out.gif` (or no `-o` to play in the terminal;
   `--demo` for a test). Web UI: drop a video / webcam → **record gif**.
9. **Identify or restyle pasted art**: `ditherlab decode art.txt -o out.png
   --scale 4` (auto-detects ascii / braille / quadrant / sextant / ANSI;
   classic `.ans/.nfo` CP437 files are read transparently),
   look at the PNG, then re-encode with new options. `ditherlab render
   art.txt -o art.png` makes a picture of the art itself.
10. **Dithered image file**: `ditherlab dither in.png -p gb -o out.png`
   (`-p auto:8` builds a palette from the image; `undither` reverses).
11. **Exploring by eye** (a human is watching): `ditherlab tui photo.jpg` —
   keys cycle mode/width/algorithm/tone/palette/theme live; `e` prints the
   equivalent command, `q` quits and prints it. `ditherlab side a.txt b.txt
   --titles "before|after"` joins two arts for comparison.
12. **Any diagram — flowchart, sequence, state machine, timeline, mindmap,
    architecture**: write it as Mermaid and `ditherlab diagram d.mmd` — the
    kind is auto-detected (`graph TD`, `sequenceDiagram` with notes /
    loop / alt / activations / autonumber, `stateDiagram-v2` with `[*]`,
    `timeline`, `mindmap`), or plain `a -> b: label` lines. `subgraph …
    end` draws labeled containers. Styles: `rounded double heavy ascii`
    + `shadow` (▒ depth) + `sketch` (hand-drawn) + `--color` (per-node
    ANSI, terminals only). Bar/column/spark charts from data: `ditherlab
    chart data.csv [--dir TB|--spark|--sorted]` — exact eighth-block
    proportions. Never hand-route arrows for more than three boxes and
    never eyeball bar lengths (references/diagrams.md).
13. **Table, tree, boxed note**: `ditherlab table data.csv|t.md|data.json
    [--style rounded|double|markdown|minimal]` (numbers right-align, wide
    characters are measured, `--max-width` wraps cells); `ditherlab tree
    outline.txt|dir|data.json` (`├──` / `└──`); `ditherlab box "text"
    --title … --style … --align center`.
14. **Before shipping anything hand-drawn or pasted**: `ditherlab lint
    art.txt` — tabs, trailing space, BOM, zero-width and double-width
    characters, ragged framed rows, box-drawing junctions that do not
    connect. `--fix` applies the safe repairs (`--pad` equalizes widths,
    `--junctions` recomputes corners/tees); `--unicode` / `--ascii`
    convert line art between `+-|` and box-drawing characters. Exit code
    1 means fix it before pasting.
15. **Nothing to hand**: `ditherlab demo [mode]`.

## Picking mode and width

| Destination / intent | Mode | Width |
| :-- | :-- | :-- |
| README / markdown | `ascii --theme readme` (braille if Unicode is fine) | ≤ 80 |
| Terminal, a human looking | `ditherlab show` (real pixels via kitty/iTerm2/sixel when `ditherlab term` says so), else `symbols` | terminal width |
| Terminal, MOTD, text required | `symbols` (highest fidelity: per-cell shapes + fg/bg color), `braille` (mono detail), `symbols --mono` | 80–140 |
| Chat | `braille` or `quadrant` | 40–70 |
| Plain-text only | `ascii -c classic` | ≤ 72 |
| Sketch / line art | `shape` (stroke matching) or `edge`; `ascii --edges` | 60–100 |
| Retro / pixel | `quadrant`, or `ansi -p gb|pico8|c64` | 60–100 |
| Shareable image of text | any mode + `-o art.svg|.html|.png` | — |
| Terminal recording / README embed | `play … -o out.cast` (asciinema) or `-o out.gif` | 60–100 |
| Subject from description | `draw` (2D scene) or `3d --scene/--text` → any mode | 50–90 |
| Tiny icon / mascot | `gallery <name>` exemplar, adapted | ≤ 12 |
| Flowchart / pipeline / states | `diagram` (Mermaid or `a -> b`), `--style ascii` for plain text | ≤ 100 |
| Table / tree / boxed note | `table` / `tree` / `box`; `--style markdown` for GitHub-rendered docs | ≤ 100 |
| CLI / README header | `figlet -f slant|small|standard`; `text --font mono` for pixel style | ≤ 80 |

Logos and icons: `--trim` drops uniform padding, `--bg #fff` composites
transparency over the page color before rendering. Older terminals and CI
logs: `--colors 256` or `--colors 16` re-quantizes truecolor escapes. Height
budget: `--rows N` shrinks the width until the art fits N lines —
use it whenever the destination has a known height (a 24-row terminal, a
chat bubble, a README section). Tune, in order: `--levels` for hazy or murky
photos (auto-levels), `--clahe 0.4` for detail hidden in shadows/skies,
`--contrast 0.2` flat → punchier; `--sharpen 0.6` mushy →
crisp; `--invert` tones backwards; `--paper` light background; `-a atkinson`
sparse/clean, `-a bayer4` retro, `-a bluenoise` grain without pattern;
`--strength 0.5` calms a busy dither; `--frame round --title` when the art
sits in prose; `--linear` (gamma-correct: mid-gray comes out ~21% ink, the
true luminance, instead of 50%) when tones look too dark or too bright;
`--oklab` for palette work (`-p gb|cga|auto:N`) so colors map by perceived
distance. Read `references/ascii-fundamentals.md` before any hand
adjustment; `references/3d-and-shading.md` for light and form.

## Rules

- Never present hand-typed art as tool output. Anything beyond a 4-line
  doodle is produced by a ditherlab command shown in the transcript, or is
  explicitly labeled hand-drawn, follows references/freehand.md, and passed
  `ditherlab lint` (exit 0) before it was pasted.
- Flowcharts, tables, trees and banners come from `diagram`, `table`,
  `tree`, `figlet` — not from hand-aligned characters.
- Paste tool output verbatim; never retouch characters.
- Look at the result before sending, and measure it: `ditherlab score art.txt
  image.png` (or MCP `score_art`) returns 0..1 structure preserved — below
  0.75 means rerun with `auto`, a wider width, or `symbols`/`braille`. This
  works for hand-drawn art against a reference image too.
- ANSI escapes go only to terminals; files and markdown get `ascii`,
  `braille`, `blocks`, or an exported `.svg/.html/.png`.
- Respect the width column; wider than the medium wraps into noise.
- A look the user approves gets saved as a theme before the turn ends.
- When settings are in doubt, run `auto` before fiddling by hand; when the
  subject is in doubt, describe geometry (`draw`, `3d --scene`) before
  typing characters.
- Exact-font output: if the destination font matters, export a glyph atlas
  from the web UI (download ▾ → glyph atlas) and `ditherlab font <file>`;
  `shape` and `render` then match that font's real glyphs.

## Example

Instead of:

```
Here's a sphere for your README:
      ___
    /     \
   |  ( )  |
    \ ___ /
```

Do:

```
$ ditherlab 3d sphere -w 46 --theme readme
[paste of the actual command output]
```

## References (read when relevant, not all at once)

- `references/ascii-fundamentals.md` — cell aspect, measured glyph density,
  stroke vocabulary, Unicode families, medium limits, composition.
- `references/3d-and-shading.md` — `ditherlab 3d`, the PGM compute-first
  method, isometric/perspective rules, shading order, materials, animation.
- `references/freehand.md` — grid passes, block letters, frames, tiny icons,
  diagrams, failure table.
- `references/themes.md` — schema, resolution order, `theme save`, config
  defaults, style-by-name workflow.
- `references/terminal-graphics.md` — `term`/`show`: kitty, iTerm2, sixel
  protocols, when pixels beat characters, reading CP437 ANSI art.
- `references/generative.md` — flow/hatch/stipple modes, `gen` kinds,
  seeds, recipes for posters and textures.
- `references/motion.md` — `fx`: cameras, reveals, particle layers, CRT,
  keyframe paths, duration taste per medium, the Director tab.
- `references/diagrams.md` — `diagram`: the Mermaid subset and `a -> b`
  syntax, styles, directions, how layout and routing work, what to do when
  a chart is too wide; `table`, `tree`, `box`, `figlet`, `lint`.
- `gallery.json` (`ditherlab gallery`) — 30 exemplars with proportion/stroke
  notes: animals, objects, symbols, UI sets, shaded sphere, isometric cube.
- `scenes`: `ditherlab draw --example …` — five worked scene files to copy.

## Observable effect

Every piece of art in a reply is preceded by the ditherlab command (or MCP
call) that produced it — `auto` when settings were uncertain, `draw`/`3d`
when the subject had no image, `diagram`/`table`/`tree`/`figlet` for
structured text — or is labeled hand-drawn with the gallery piece / theme /
reference it followed and a `lint` result; doubtful results show a
`score`; pasted art gets a `decode`; a liked look ends in `theme save`.
The eval counts exactly this.

