Communitygithub.com

daronthedragon/ditherlab

Dithering & ASCII art, both directions: image → braille/ASCII/ANSI/dithered PNG and back. Local web UI + zero-dep CLI + agent skill.

What is ditherlab?

ditherlab is a Claude Code agent skill that dithering & ASCII art, both directions: image → braille/ASCII/ANSI/dithered PNG and back. Local web UI + zero-dep CLI + agent skill.

Works withClaude CodeCodex CLICursorGemini CLIWindsurf
npx skills add daronthedragon/ditherlab

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

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 / intentModeWidth
README / markdownascii --theme readme (braille if Unicode is fine)≤ 80
Terminal, a human lookingditherlab show (real pixels via kitty/iTerm2/sixel when ditherlab term says so), else symbolsterminal width
Terminal, MOTD, text requiredsymbols (highest fidelity: per-cell shapes + fg/bg color), braille (mono detail), symbols --mono80–140
Chatbraille or quadrant40–70
Plain-text onlyascii -c classic≤ 72
Sketch / line artshape (stroke matching) or edge; ascii --edges60–100
Retro / pixelquadrant, or `ansi -p gbpico8
Shareable image of textany mode + `-o art.svg.html
Terminal recording / README embedplay … -o out.cast (asciinema) or -o out.gif60–100
Subject from descriptiondraw (2D scene) or 3d --scene/--text → any mode50–90
Tiny icon / mascotgallery <name> exemplar, adapted≤ 12
Flowchart / pipeline / statesdiagram (Mermaid or a -> b), --style ascii for plain text≤ 100
Table / tree / boxed notetable / tree / box; --style markdown for GitHub-rendered docs≤ 100
CLI / README header`figlet -f slantsmall

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.mdditherlab 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.mdterm/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.mdfx: cameras, reveals, particle layers, CRT, keyframe paths, duration taste per medium, the Director tab.
  • references/diagrams.mddiagram: 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.

Related Skills