3 Punkte von GN⁺ 2024-06-08 | 1 Kommentare | Auf WhatsApp teilen
  • ASCII Silhouettify ist eine Browser- und Kommandozeilen-App, die flächige, kontrastreiche Grafiken wie Logos, Banner und Pixel Art in Silhouetten-ASCII-Art umwandelt, die ausschließlich mit 95 druckbaren ASCII-Zeichen gefüllt ist
  • Als Eingabe werden png, svg, jpg, webp, gif, tif, heif, avif und pdf unterstützt; da jedoch Schattierungen, Highlights, Schatten und Farbverläufe nicht gerendert werden, ist es nicht für die Umwandlung von Fotos geeignet
  • Die Ausgabe unterstützt ANSI-Farbtext, Klartext, HTML und das benutzerdefinierte ASCII-Art-Format von Neofetch; das Neofetch-Format ist auf 6 Farben aus der erweiterten ANSI-Palette mit 256 Farben begrenzt
  • Der Umwandlungsalgorithmus zerlegt ein Bild in Farbebenen und wählt dann für jeden 9×19-Pixel-Bereich das größte Zeichen unter den ASCII-Zeichen aus, das nicht in die Kontur der Silhouette hineinragt
  • Für die Performance nutzt er einen 95-Bit-Akkumulator, 171 Bitmasken, Leading-Zeros-Berechnung und Parallelisierung über logische Prozessoren; für das Palette-Matching kommt die rechenintensive CIEDE2000-Formel für wahrgenommene Farbunterschiede zum Einsatz

App zur Umwandlung in ASCII-Silhouetten

  • ASCII Silhouettify ist eine App, die Bilder in ASCII-Silhouetten umwandelt
    • Eine ASCII-Silhouette ist ein Stil von ASCII-Art, bei dem gleichmäßig gefüllte geometrische Formen stärker hervortreten als Linien oder Texturen
    • Sie eignet sich gut für minimalistische, kontrastreiche flächige Grafiken ohne räumliche Tiefe, etwa Logos, Banner und Pixel Art
    • Da Schattierungen, Highlights, Schatten und Farbverläufe nicht gerendert werden, ist sie nicht für Fotos geeignet
  • Der Zeichensatz ist auf die 95 druckbaren ASCII-Zeichen beschränkt, das traditionelle Medium von ASCII-Künstlern
    • Linien- und Blockzeichen, wie sie in ANSI-Art üblich sind, sowie viele Unicode-Zeichen aus Kaomoji werden nicht verwendet
  • Das Ausgabeformat hängt von den Einstellungen ab
    • Einfarbiger Klartext
    • Text mit Farben über ANSI-Escape-Sequenzen
    • HTML mit oder ohne Farbe
    • Neofetch-ASCII-Art-Format
  • Es handelt sich um eine Desktop-App, die im Browser und auf der Kommandozeile genutzt werden kann

Ubuntu-Logo und Neofetch-Beispiel

  • Das Beispiel zeigt den Ablauf, bei dem das Ergebnis von ASCII Silhouettify in die Ausgabe von Neofetch auf einer Ubuntu-Instanz eingefügt wird
  • Um optimale ASCII-Art zu erhalten, wird ein hochauflösendes Ubuntu-Logo aus dem Web geholt und zunächst auf die Größe skaliert, in der es in der Konsole erscheinen soll
  • Wenn das Bild mit der Kommandozeilenversion umgewandelt wird, entsteht standardmäßig farbiger Text mit ANSI-Escape-Sequenzen
  • Mit dem Flag -o lässt sich die Ausgabe in eine Datei schreiben, die Neofetch anzeigen soll
  • Da Neofetch zwischen ANSI-Art und OS-Metriken einen großen Abstand einfügt, nutzt das Beispiel das benutzerdefinierte ASCII-Art-Dateiformat von Neofetch
    • Die erste Zeile der Ausgabedatei ist eine Liste von Farbindizes
    • Die folgenden Zeilen enthalten das codierte Bild
    • Die erste Zeile wird in einem Texteditor in die Zwischenablage kopiert und anschließend entfernt
    • Beim Ausführen von Neofetch wird der in der Zwischenablage gespeicherte Wert eingefügt und verwendet
    • Für eine dauerhafte Anwendung wird ein Teil des Neofetch-Bash-Skripts durch denselben Wert ersetzt
  • Wenn man das ursprüngliche Logo über das erzeugte Ergebnis legt und vergleicht, wird sichtbar, wie der Algorithmus das größte Zeichen auswählt, das in die Kontur jedes Farbbereichs passt

Installation und Deinstallation

  • Die Kommandozeilenversion ist eine Node.js-Anwendung
  • Falls Node.js nicht vorhanden ist, muss zunächst die Node.js-Installation durchgeführt werden
  • Unter macOS und Linux ist eine npm-Konfiguration erforderlich, damit eine globale Installation ohne Root-Benutzer möglich ist
  • Installationsbefehl:
    • npm install -g ascii-silhouettify
  • Deinstallationsbefehl:
    • npm uninstall -g ascii-silhouettify

Eingabe- und Ausgabeoptionen

  • Die Browser- und die Kommandozeilenversion unterstützen denselben Optionsumfang
    • Das Flag -h der Kommandozeilenversion gibt eine Zusammenfassung der Optionen aus
  • Mehrere Bilder können auf einmal umgewandelt werden
    • Unterstützte Formate sind png, svg, jpg, webp, gif, tif, heif, avif und pdf
    • Das Flag -i der Kommandozeilenversion akzeptiert mehrere Regeln zum Abgleich von Dateinamenmustern
    • Eingabebilder sollten einen schwarzen oder transparenten Hintergrund haben
  • Die Ausgabe ist in vier Gruppen unterteilt
    • Klartext oder ANSI-Farbtext
    • Monospace-Text im HTML-Format
    • Benutzerdefiniertes ASCII-Art-Format von Neofetch
    • Das Neofetch-Format ist auf 6 Farben aus der erweiterten ANSI-Palette mit 256 Farben begrenzt
  • Der Standardwert für die Palette sind 240 Farben aus der erweiterten ANSI-Palette mit 256 Farben, ausgenommen die standardmäßige ANSI-Palette mit 16 Farben
    • Die 16 Farben der Standard-ANSI-Palette werden in modernen Terminal-Emulatoren häufig neu definiert und sind deshalb standardmäßig ausgeschlossen
    • Nutzer können die ersten 8 Farben der Standard-ANSI-Palette, die gesamte Standard-ANSI-Palette mit 16 Farben, die gesamte erweiterte ANSI-Palette mit 256 Farben oder die standardmäßige 240-Farben-Palette auswählen
  • Die maximale Anzahl der in der Ausgabe erscheinenden Farben kann festgelegt werden
    • Farben, die als schwarzer Hintergrund betrachtet werden, werden nicht mitgezählt
    • Der Standardwert ist 255
    • Der einfarbige Modus setzt diesen Wert faktisch auf 1
    • Der Standardwert für das benutzerdefinierte ASCII-Art-Format von Neofetch ist 6, der Maximalwert dieses Formats

Anzeigegröße und Anpassung der Umwandlungsqualität

  • Das Seitenverhältnis der erzeugten ASCII-Art in einem Terminal-Emulator hängt von Schriftart, Schriftgröße, Zeilenhöhe und den Rundungsregeln für Zeichengrößen ab
  • Zur Optimierung wird ein Bild des Terminaltexts aufgenommen und die Pixelgröße jedes Monospace-Zeichens einschließlich des Abstands zwischen den Zeilen gemessen
  • Messbeispiele vom Windows-Desktop des Entwicklers sind wie folgt
    • IntelliJ Terminal: Zeichen 8×22, Schriftgröße 10, Zeilenhöhe 1,65
    • Putty: Zeichen 8×16, Schriftgröße 10, Zeilenhöhe 1,2
    • Notepad: Zeichen 10×18, Schriftgröße 13, Zeilenhöhe 1,04
    • Notepad++: Zeichen 9×19, Schriftgröße 12, Zeilenhöhe 1,2
    • Windows Command Prompt: Zeichen 8×16, Schriftgröße 10, Zeilenhöhe 1,2
    • Windows Console Host: Zeichen 9×20, Schriftgröße 12, Zeilenhöhe 1,25
    • Windows Terminal: Zeichen 9×19, Schriftgröße 12, Zeilenhöhe 1,2
  • Idealerweise wird das Eingabebild in einem Malprogramm vorab auf die gewünschte Größe skaliert, in der es im Terminal angezeigt werden soll
    • Für kleine Anpassungen akzeptiert ASCII Silhouettify einen Skalierungsfaktor für das Bild
    • Der Standardwert ist 1
  • Der Umwandlungsalgorithmus ersetzt Bereiche mit weniger als 5 % Helligkeit durch Leerzeichen, damit der schwarze Hintergrund vollständig sichtbar wird
    • Nutzer können diesen Dunkelheitsschwellenwert anpassen
  • Standardmäßig wird die Arbeit auf alle verfügbaren logischen Prozessoren verteilt
    • Nutzer können die Zahl der zugewiesenen Prozessoren bis auf 1 reduzieren
    • Eine Verringerung der Prozessorzahl verlängert die Verarbeitungszeit

Umwandlungsalgorithmus

  • Auf dem Windows-Desktop, auf dem der Entwickler ASCII Silhouettify erstellt hat, rendert Terminal jedes Monospace-Zeichen in ein Rechteck von 9×19 Pixeln, wenn die Standardeinstellung Cascadia Mono mit 12 Punkt und 1,2em verwendet wird
  • Der Algorithmus erfasst Bilder der 95 druckbaren ASCII-Zeichen und schwellwertet sie bei 50 % Intensität, um Zeichenbilder zu erzeugen, die nur schwarze und weiße Pixel enthalten
  • Das Quellbild wird in eindeutige Farbebenen zerlegt
    • Jede Ebene ist eine weiße Silhouette auf schwarzem Hintergrund
  • Jede Farbebene wird in eine Matrix aus rechteckigen Bereichen von 9×19 Pixeln aufgeteilt
    • Jeder Bereich wird durch ein ASCII-Zeichen ersetzt
  • Das optimale Zeichen wird ausgewählt, indem der Bereich und alle ASCII-Zeichenbilder pixelweise verglichen werden
    • Wenn sich weiße Pixel des Zeichenbilds mit schwarzen Pixeln des Bereichs überschneiden, wird dieses Zeichen ausgeschlossen, damit die Kontur der Silhouette nicht verzerrt wird
    • Unter den verbleibenden Zeichen wird das Zeichen mit der höchsten Anzahl übereinstimmender weißer Pixel ausgewählt
  • Beim Ersetzen eines Bereichs durch ein Zeichen wird die Anzahl der übereinstimmenden weißen Pixel aufgezeichnet
    • Nachdem alle Ebenen umgewandelt wurden, werden die Ebenen kombiniert, indem das Zeichen mit der höchsten Anzahl übereinstimmender weißer Pixel ausgewählt wird
    • Das endgültige Zeichen wird in der Farbe der Ebene eingefärbt, aus der dieses Zeichen stammt

Beschleunigung auf Bitmaskenbasis

  • Vor der Umwandlung werden die ASCII-Zeichenbilder nach der Anzahl ihrer weißen Pixel sortiert
    • Das Leerzeichen hat mit 0 die wenigsten weißen Pixel
    • Das Zeichen @ hat die meisten weißen Pixel
  • Der Algorithmus vergleicht die Zeichenbilder mit jedem Bereich, beginnend bei @ und dann absteigend
    • Sobald ein Zeichen gefunden wird, das vollständig in die Silhouette passt, wird der Bereich durch dieses Zeichen ersetzt
    • Durch die Sortierung ist dieses Zeichen der Kandidat mit der größten Anzahl weißer Pixel
  • Um die Geschwindigkeit stark zu erhöhen, werden für jedes Pixel eines 9×19-Bereichs 171 Bitmasken vorbereitet
    • Jede Bitmaske repräsentiert die Menge der ASCII-Zeichenbilder, die an dieser Koordinate ein schwarzes Pixel haben
    • Jede Bitmaske enthält 95 Bits
    • bit-0 entspricht dem Leerzeichen, bit-94 dem Zeichen @
  • Während der Umwandlung eines Bereichs wird die Kandidatenmenge verfügbarer ASCII-Zeichen mit einem 95-Bit-Akkumulator schrittweise eingegrenzt
    • Zu Beginn wird der Akkumulator mit allen Bits auf 1 initialisiert
    • Für jedes schwarze Pixel im Bereich wird der aktuelle Akkumulator per bitweisem AND mit der Bitmaske dieses Pixels verknüpft
    • Diese Operation schließt Zeichenbilder aus, die an der Position eines schwarzen Pixels des Bereichs ein weißes Pixel haben
  • Nachdem der gesamte Bereich verarbeitet ist, sind die gesetzten Bits des Akkumulators ersetzbare Zeichenkandidaten
    • Da die Zeichen sortiert sind, ergibt die Anzahl der Leading Zeros im Akkumulator den Index des ASCII-Zeichenbilds mit den meisten weißen Pixeln, das vollständig in der Silhouette enthalten ist
    • Mithilfe einer Library wird der Leading-Zeros-Berechnungsbefehl des Mikroprozessors aufgerufen, um den benötigten Wert schnell zu erhalten

Optimierung des Ursprungs und Farbabgleich

  • Beim Aufteilen des Quellbilds in eine Matrix rechteckiger Bereiche beeinflusst der Ursprung der Matrix das Ergebnis
  • Zur Optimierung des Ergebnisses wiederholt der Algorithmus die Umwandlung des gesamten Bildes für alle ganzzahligen Koordinatenursprünge innerhalb eines 9×19-Pixel-Bereichs um den Bildursprung
  • Um das hohe Verarbeitungsvolumen zu bewältigen, wird die Arbeit auf die verfügbaren logischen Prozessoren verteilt
  • Die Farbpalette kann je nach Nutzereinstellung von den ersten 8 Farben der Standard-ANSI-Palette bis zur gesamten erweiterten ANSI-Palette mit 256 Farben eingeschränkt werden
  • Beim Zerlegen des Quellbilds in eindeutige Farbebenen wird die rechenintensive CIEDE2000-Formel für wahrgenommene Farbunterschiede verwendet, um die nächstgelegene Farbe in der Palette zu finden

Quellcode

1 Kommentare

 
GN⁺ 2024-06-08
Meinungen auf Hacker News
  • Die coolste Seite auf dieser Site ist wohl die Farbgalerie: https://meatfighter.com/ascii-silhouettify/color-gallery.htm...

    • Das Wendy's-Logo ist ein bisschen unheimlich
    • Ohne Mastodon-Logo ist diese Seite ungültig
    • Das Z-Logo ist wirklich clever
      Das fühlt sich so an, als würde man Icon-Grafikdesign aus einer anderen Perspektive sehen
  • Ich habe ein ähnliches Tool gebaut, um Game-Sprites zu erstellen, die man direkt in Code einfügen kann: https://memalign.github.io/m/pceimage/index.html
    Es läuft im Web, und auch die farbige ASCII-Ausgabe lässt sich bearbeiten
    Allerdings ist es etwas knifflig, gute Ergebnisse zu bekommen, weil man Wobble manuell ausschalten und die Pixel-Sampling-Größe anpassen muss

    • Wirklich spaßig, gefällt mir
      Als Vorschlag: Schön wäre ein Modus, der das Wackeln entfernt, aber die niedliche Anmutung beibehält, die durch dickere Formen und abgerundete Ecken entsteht
  • Wenn du ASCII-Art magst, dürfte dir auch ein animiertes ASCII-Tool gefallen, das GIFs in ASCII umwandelt: https://www.gifcii.fun
    Nebenbei: Ich habe es selbst gebaut

    • Als jemand, der GIFs mag, finde ich das wirklich unterhaltsam
      Wäre schön, wenn man es irgendwie speichern könnte; zum Beispiel wäre ein Export zurück als GIF oder als Video cool
  • Die Web-Version kommt in Chromium-basierten Browsern nicht zum Ende, aber die CLI-Version funktioniert: https://meatfighter.com/ascii-silhouettify/spa/index.html#/
    Als Bonus habe ich auch große ASCII-Art gebaut, die wie das HN-Logo aussieht

  • Tolle Arbeit, erinnert mich an die farbige Telnet Matrix :)
    Später habe ich auch https://ascii.theater/ entdeckt
    Vor ein paar Jahren habe ich etwas Ähnliches für einen Bildkonverter für Retro-Computer gebaut; dabei habe ich die Monospace-Schrift dieses Computers verwendet und vor der Zeichenumwandlung auch Dithering angewendet
    Denn dadurch entstanden in Fotos weichere Verläufe: https://github.com/KodeMunkie/imagetozxspec/blob/master/src/...

  • „Was gewesen ist, wird wieder sein, und was getan wurde, wird wieder getan werden. Es gibt nichts Neues unter der Sonne.“
    Gut gemacht
    Früher haben wir mit EBCDIC und ASCII die Druckdichte von Zeichen genutzt, um Geburtstagsbanner und Bilder ganz ähnlich auf Endlospapier-Banddruckern und später auf Nadeldruckern auszugeben

  • Ich glaube, heute werden ziemlich viele Leute /etc/motd oder /etc/issue ändern

  • Ich habe etwas Ähnliches mit einer sich in Echtzeit bewegenden wobbelnden Funktion ausprobiert: https://piter-genuary2024.netlify.app/genuary9/

    • Ich frage mich, ob man daraus etwas Gruseliges machen könnte: beginnend mit einer normalen tail-Ausgabe von Logs, dann immer sichtbarere Muster hineinmischend, bis schließlich ein unheimliches Gesicht zwischen dem Text erscheint
  • Schon wieder npm
    Das Projekt ist großartig, aber ich weiß nicht, warum es unbedingt so laufen muss
    Wo ist die ganz normale Installationsweise geblieben?

    • Ich bin neugierig, welche Alternative du vorschlagen würdest
      NPM funktioniert überall auf die gleiche Weise, und es gibt keinen Paketmanager, der über so viele Plattformen hinweg so verbreitet ist wie NPM
    • Wenn du erklärst, was du hier mit „normaler Installation“ meinst, kann ich dir die Probleme dieses Ansatzes nennen
    • Man muss es nicht einmal installieren
      Einfach mit npx ausführen
    • Stimmt, ich weiß auch nicht, was aus der normalen Installationsweise geworden ist – oder ob es sie überhaupt je gab
      Andere Setups dauern Stunden und enden im Chaos, deshalb verbinde ich meine CLI-Repositories überall mit npm/yarn link
      Sogar Python-Skripte entwickle ich mit nodemon main.py; manchmal scheint es, als wüssten nur die Node-Leute, was man wirklich braucht
  • Trotzdem werde ich wohl weiter https://asciiflow.com/# statt Figma verwenden