Back

ASCII-Art im Browser und Terminal

ASCII-Art im Browser und Terminal

Die Idee ist einfach: Man nimmt ein Bild, misst die Helligkeit jedes Pixels und ersetzt ihn durch ein Zeichen. Dichte Zeichen wie @ oder # repräsentieren dunkle Bereiche, während hellere wie . oder helle Bereiche darstellen. Reiht man genügend solcher Ersetzungen über ein Raster aneinander, erhält man ein erkennbares Bild, das vollständig aus Text besteht.

Diese Grundidee treibt sowohl ASCII-Art im Terminal als auch ASCII-Art im Browser an, und moderne Implementierungen haben sie weit über das klassische 7-Bit-ASCII hinausgeführt.

Wichtigste Erkenntnisse

  • ASCII-Art bildet Pixelhelligkeit auf Zeichen aus einer sortierten Palette ab, wobei dichte Glyphen wie @ dunkle Bereiche und spärliche wie . helle Bereiche darstellen
  • Unicode-Blockelemente und Braille-Muster bieten eine deutlich feinere Auflösung als traditionelle ASCII-Zeichenpaletten
  • Browser-Implementierungen basieren auf <canvas>-Pixeldaten und monospaced CSS, während Terminal-Renderer ANSI-Escape-Sequenzen für Farben verwenden
  • Terminal-Fähigkeiten variieren stark – von einfachem 16-Farben-ANSI über 24-Bit-True-Color bis hin zu SIXEL und dem Kitty-Grafikprotokoll

Wie die Pixel-zu-Zeichen-Zuordnung funktioniert

Jeder ASCII-Renderer folgt in etwa derselben Pipeline:

  1. Das Quellbild oder den Video-Frame in ein Raster von Zellen abtasten
  2. Die durchschnittliche Helligkeit (Luminanz) jeder Zelle berechnen
  3. Diesen Helligkeitswert einem Zeichen aus einer sortierten Palette zuordnen
  4. Das resultierende Zeichenraster mit optionaler Farbe ausgeben

Eine einfache JavaScript-Implementierung sieht so aus:

const palette = ' .:-=+*#%@';

function brightnessToChar(brightness) {
  const index = Math.floor((brightness / 255) * (palette.length - 1));
  return palette[index];
}

Hier wird erwartet, dass brightness ein Wert zwischen 0 (schwarz) und 255 (weiß) ist. Die Funktion normalisiert ihn zu einem Index innerhalb der Palette-Zeichenkette, wobei frühere Zeichen hellere Töne und spätere Zeichen dunklere darstellen.

Die Qualität der Ausgabe hängt stark von Ihrer Zeichenpalette ab. Klassisches ASCII bietet etwa 10–15 nutzbare Schattierungsstufen. Moderne Implementierungen schneiden besser ab.

Über ASCII hinaus: Textmodus-Grafiken mit Unicode

Textmodus-Grafiken mit Unicode ermöglichen eine deutlich feinere Auflösung. Anstelle einer spärlichen ASCII-Palette können Sie verwenden:

  • Blockelemente (█ ▓ ▒ ░) für vier Schattierungsstufen pro Zelle
  • Braille-Muster (⣿ ⠿ ⠛), die bis zu 8 Punkte in einem einzigen Zeichen kodieren und eine höhere effektive Auflösung als traditionelle ASCII-Paletten ermöglichen
  • Box-Drawing-Zeichen für strukturierte Layouts und Rahmen

Chafa, ein Terminal-Bildbetrachter, verwendet Unicode-Block- und Braille-Zeichen, um Bilder in nahezu fotografischer Qualität im Terminal darzustellen. Der Unterschied zu reinem ASCII ist beeindruckend.

ASCII-Art im Browser: Canvas- und WebGL-Ansätze

Browser-basiertes JavaScript-ASCII-Rendering verwendet typischerweise ein <canvas>-Element als Bildquelle. Der Prozess:

  1. Ein Bild oder Video-Frame auf ein Offscreen-Canvas zeichnen
  2. Pixeldaten mit ctx.getImageData() auslesen
  3. Das Pixelraster abtasten und jede Zelle einem Zeichen zuordnen
  4. Das Ergebnis in ein <pre>-Element oder zurück auf ein Canvas mit fillText() rendern

Bibliotheken wie p5.js machen dies unkompliziert und ermöglichen die Verarbeitung von Live-Webcam-Feeds oder Video-Frames in Echtzeit. Für höhere Performance können WebGL-Shader die Helligkeitsabtastung und Zeichenzuordnung auf der GPU übernehmen, was wichtig ist, wenn Sie vollständiges Video mit 30 fps rendern.

Für die statische Anzeige ist das HTML/CSS-Setup minimal, aber wichtig:

.ascii-art {
  font-family: monospace;
  white-space: pre;
  line-height: 1;
  letter-spacing: 0;
}

Ohne white-space: pre kollabiert der Browser Leerzeichen und zerstört das Layout. Ohne eine Monospace-Schriftart haben Zeichen ungleiche Breiten und das Raster zerfällt. Das Setzen von letter-spacing: 0 verhindert subtile horizontale Lücken, die einige Browser standardmäßig einfügen.

Terminal-ASCII-Grafiken: ANSI-Farben und Protokollvariabilität

In Terminal-Umgebungen werden ASCII- oder Unicode-Zeichen auf die Standardausgabe geschrieben. Farbe wird durch ANSI-Escape-Sequenzen hinzugefügt. Moderne Terminals unterstützen 24-Bit-(True-Color-)Ausgabe:

printf '\033[38;2;255;100;0m%s\033[0m\n' "orange text"

Dies setzt die Vordergrundfarbe auf RGB(255, 100, 0) unter Verwendung der 38;2;R;G;B-Sequenz und setzt dann die Formatierung mit \033[0m zurück.

Tools wie jp2a und ascii-image-converter verwenden diesen Ansatz, um farbige Terminal-ASCII-Grafiken aus Bilddateien zu erzeugen.

Die Terminal-Fähigkeiten variieren jedoch erheblich. Einige Terminals unterstützen nur einfaches 16-Farben-ANSI. Andere unterstützen 256-Farben-Modus, vollständiges 24-Bit-True-Color, SIXEL-Grafiken oder das Kitty-Grafikprotokoll, das tatsächliche Pixelbilder innerhalb des Terminals rendern kann, anstatt Zeichenapproximationen. Die Unicode-Breitenbehandlung unterscheidet sich auch zwischen Terminals, sodass Braille- oder breite Zeichen je nach Umgebung falsch ausgerichtet sein können.

Fazit

Ob Sie einen JavaScript-ASCII-Renderer für einen Browser schreiben oder Bilddaten durch ein Terminal-Tool leiten – die zugrunde liegende Logik ist identisch: Pixel werden zu Zeichen, Helligkeit wird zu Dichte und Farbe wird zu Escape-Codes oder CSS. Der Browser gibt Ihnen präzise Kontrolle über Schriftarten und Layout, während das Terminal Ihnen Geschwindigkeit und Komponierbarkeit bietet. Die Wahl der Umgebung prägt das Tooling, aber die Konvertierungs-Pipeline – Abtasten, Messen, Zuordnen, Rendern – bleibt dieselbe.

FAQs

Die meisten Monospace-Schriftzeichen sind höher als breit, sodass jede Zeichenzelle kein perfektes Quadrat ist. Diese vertikale Streckung verzerrt das Bild. Sie können dies kompensieren, indem Sie die line-height in CSS anpassen, das Quellbild vor der Konvertierung auf ein nicht-quadratisches Seitenverhältnis skalieren oder weniger Zeilen im Verhältnis zu Spalten abtasten.

Ordnen Sie Zeichen nach ihrer visuellen Dichte, von hellsten bis dunkelsten. Eine längere Palette gibt Ihnen mehr Schattierungsstufen und weichere Verläufe. Testen Sie Ihre Palette, indem Sie ein Verlaufsbild rendern und auf sichtbare Bänderung prüfen. Unicode-Blockelemente und Braille-Muster bieten feinere Granularität als Standard-ASCII-Zeichen.

Ja. Im Browser zeichnen Sie jeden Video-Frame auf ein Offscreen-Canvas, lesen die Pixeldaten aus und ordnen Zellen bei jedem Animations-Frame Zeichen zu. Für akzeptable Performance bei 30 fps halten Sie die Zeichenraster-Auflösung moderat oder lagern die Helligkeitsberechnung auf einen WebGL-Shader aus. Terminal-Tools wie Chafa unterstützen ebenfalls Video-Eingabe.

Braille-Zeichen sind Unicode und ihre gerenderte Breite hängt vom Terminal-Emulator und der aktiven Schriftart ab. Einige Terminals behandeln sie als breite Zeichen, andere als schmale. Wenn Ihre Ausgabe fehlerhaft aussieht, testen Sie mit einem anderen Terminal oder einer anderen Schriftart. Tools wie Chafa erkennen Terminal-Fähigkeiten und passen ihren Ausgabemodus entsprechend an.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay