3 points par GN⁺ 2024-06-08 | 1 commentaires | Partager sur WhatsApp
  • ASCII Silhouettify est une application navigateur et en ligne de commande qui transforme des graphismes plats et très contrastés comme des logos, bannières ou pixel art en silhouettes ASCII remplies uniquement avec 95 caractères ASCII imprimables
  • Accepte en entrée png, svg, jpg, webp, gif, tif, heif, avif, pdf, mais comme l’outil ne restitue ni ombrage, ni reflets, ni ombres, ni dégradés, il ne convient pas à la conversion de photos
  • La sortie prend en charge le texte en couleur ANSI, le texte brut, le HTML, et le format d’art ASCII personnalisé de Neofetch ; le format Neofetch est limité à 6 couleurs parmi la palette ANSI étendue 256 couleurs
  • L’algorithme de conversion découpe l’image en plans de couleur puis choisit, dans chaque zone de 9×19 pixels, le plus grand caractère ASCII qui ne déborde pas du contour de la silhouette
  • Pour les performances, l’outil utilise un accumulateur de 95 bits, 171 masques de bits, le calcul des zéros de tête, le traitement parallèle sur processeurs logiques, et applique pour l’association de palette la formule de différence perceptuelle de couleur CIEDE2000, coûteuse en calcul

Application de conversion en silhouettes ASCII

  • ASCII Silhouettify est une application qui transforme des images en silhouettes ASCII
    • Une silhouette ASCII est un style d’art ASCII où les formes géométriques remplies de manière uniforme ressortent davantage que les lignes ou les textures
    • Elle convient bien aux graphismes plats minimalistes, très contrastés et sans profondeur volumétrique, comme les logos, bannières ou pixel art
    • Comme elle ne restitue ni ombrage, ni reflets, ni ombres, ni dégradés, elle n’est pas adaptée aux photos
  • Le jeu de caractères est limité aux 95 caractères ASCII imprimables, le médium traditionnel des artistes ASCII
    • Les caractères de ligne ou de bloc fréquents dans l’art ANSI, ainsi que de nombreux caractères Unicode utilisés dans les kaomoji, ne sont pas employés
  • Les formats de sortie varient selon la configuration
    • Texte brut monochrome
    • Texte coloré avec séquences d’échappement ANSI
    • HTML avec ou sans couleur
    • Format d’art ASCII Neofetch
  • C’est une application desktop utilisable dans le navigateur et en ligne de commande

Exemple avec le logo Ubuntu et Neofetch

  • L’exemple montre le processus consistant à intégrer le résultat d’ASCII Silhouettify dans la sortie de Neofetch sur une instance Ubuntu
  • Pour obtenir le meilleur art ASCII possible, une image haute résolution du logo Ubuntu est récupérée sur le web puis redimensionnée à la taille d’affichage visée dans la console
  • La conversion de l’image avec la version en ligne de commande produit par défaut un texte coloré avec séquences d’échappement ANSI
  • Le drapeau -o permet d’envoyer la sortie vers un fichier que Neofetch affichera
  • Comme Neofetch insère un grand espace entre l’art ANSI et les informations système, l’exemple utilise le format de fichier d’art ASCII personnalisé de Neofetch
    • La première ligne du fichier de sortie est une liste d’indices de couleur
    • Les lignes suivantes contiennent l’image encodée
    • Dans un éditeur de texte, on copie la première ligne dans le presse-papiers puis on la supprime
    • Lors de l’exécution de Neofetch, on colle la valeur conservée dans le presse-papiers
    • Pour l’appliquer de façon permanente, on remplace une partie du script bash de Neofetch par cette même valeur
  • En superposant le logo d’origine au résultat généré pour les comparer, on voit que l’algorithme choisit le plus grand caractère qui tient dans le contour de chaque zone colorée

Installation et suppression

  • La version en ligne de commande est une application Node.js
  • Si Node.js n’est pas installé, il faut d’abord suivre la procédure d’installation de Node.js
  • Sur macOS et Linux, une configuration npm est nécessaire pour permettre une installation globale sans utilisateur root
  • Commande d’installation :
    • npm install -g ascii-silhouettify
  • Commande de suppression :
    • npm uninstall -g ascii-silhouettify

Options d’entrée et de sortie

  • Les versions navigateur et ligne de commande prennent en charge le même ensemble d’options
    • Le drapeau -h de la version en ligne de commande affiche un message récapitulatif des options
  • Il est possible de convertir plusieurs images à la fois
    • Les formats pris en charge sont png, svg, jpg, webp, gif, tif, heif, avif, pdf
    • Le drapeau -i de la version en ligne de commande accepte plusieurs règles de correspondance de noms de fichiers
    • Les images d’entrée doivent avoir un fond noir ou transparent
  • La sortie se répartit en quatre familles
    • Texte brut ou texte couleur ANSI
    • Texte à chasse fixe au format HTML
    • Format d’art ASCII personnalisé de Neofetch
    • Le format Neofetch est limité à 6 couleurs parmi la palette ANSI étendue 256 couleurs
  • La palette par défaut se compose de 240 couleurs, soit la palette ANSI étendue 256 couleurs sans la palette ANSI standard de 16 couleurs
    • Les 16 couleurs de la palette ANSI standard sont souvent redéfinies dans les émulateurs de terminal modernes, elles sont donc exclues par défaut
    • L’utilisateur peut choisir les 8 premières couleurs de la palette ANSI standard, l’ensemble des 16 couleurs ANSI standard, les 256 couleurs ANSI étendues complètes, ou la palette par défaut de 240 couleurs
  • Il est possible de définir le nombre maximal de couleurs visibles dans la sortie
    • Les couleurs considérées comme fond noir ne sont pas comptées
    • La valeur par défaut est 255
    • Le mode monochrome revient en pratique à définir cette valeur à 1
    • La valeur par défaut du format d’art ASCII personnalisé de Neofetch est 6, soit le maximum permis par ce format

Ajustement de la taille d’affichage et de la qualité de conversion

  • Le ratio largeur/hauteur de l’art ASCII généré dans un émulateur de terminal dépend de la police, de sa taille, de l’interligne et des règles d’arrondi de la taille des caractères
  • Pour optimiser le résultat, l’image texte du terminal est capturée puis la taille en pixels de chaque caractère à chasse fixe, y compris l’espace entre les lignes, est mesurée
  • Exemples de mesures sur le bureau Windows du développeur
    • IntelliJ Terminal : caractère 8×22, taille de police 10, interligne 1.65
    • Putty : caractère 8×16, taille de police 10, interligne 1.2
    • Notepad : caractère 10×18, taille de police 13, interligne 1.04
    • Notepad++ : caractère 9×19, taille de police 12, interligne 1.2
    • Windows Command Prompt : caractère 8×16, taille de police 10, interligne 1.2
    • Windows Console Host : caractère 9×20, taille de police 12, interligne 1.25
    • Windows Terminal : caractère 9×19, taille de police 12, interligne 1.2
  • Idéalement, l’image d’entrée doit être redimensionnée à l’avance dans un logiciel de dessin selon la taille souhaitée dans le terminal
    • Pour de petits ajustements, ASCII Silhouettify accepte un coefficient d’échelle d’image
    • La valeur par défaut est 1
  • L’algorithme de conversion remplace les zones de luminosité inférieure à 5 % par des espaces afin de laisser apparaître entièrement le fond noir
    • L’utilisateur peut ajuster ce seuil d’obscurité
  • Par défaut, le travail est réparti sur tous les processeurs logiques disponibles
    • L’utilisateur peut réduire le nombre de processeurs alloués jusqu’à 1
    • Réduire le nombre de processeurs allonge le temps de traitement

Algorithme de conversion

  • Sur le bureau Windows du développeur ayant créé ASCII Silhouettify, Terminal rend chaque caractère à chasse fixe dans un rectangle de 9×19 pixels avec les réglages par défaut Cascadia Mono 12 points, 1.2em
  • L’algorithme capture les images des 95 caractères ASCII imprimables, puis leur applique un seuillage à 50 % d’intensité pour obtenir des images de caractères ne contenant que des pixels noirs et blancs
  • L’image source est séparée en plans de couleurs uniques
    • Chaque plan est une silhouette blanche sur fond noir
  • Chaque plan de couleur est découpé en une matrice de zones rectangulaires de 9×19 pixels
    • Chaque zone est remplacée par un seul caractère ASCII
  • Le caractère optimal est choisi en comparant, pixel par pixel, la zone à toutes les images de caractères ASCII
    • Si les pixels blancs d’une image de caractère se superposent à des pixels noirs de la zone, ce caractère est exclu afin de ne pas déformer le contour de la silhouette
    • Parmi les caractères restants, celui qui possède le plus grand nombre de pixels blancs correspondants est sélectionné
  • Lors du remplacement d’une zone par un caractère, le nombre de pixels blancs correspondants est enregistré
    • Une fois tous les plans convertis, les plans sont fusionnés en choisissant le caractère ayant le plus grand nombre de pixels blancs correspondants
    • Le caractère final est coloré avec la couleur du plan dont il provient

Accélération basée sur des bitmasks

  • Avant la conversion, les images des caractères ASCII sont triées selon leur nombre de pixels blancs
    • Le caractère espace en a 0, soit le minimum
    • Le caractère @ en a le plus
  • L’algorithme compare chaque zone aux images des caractères en partant de @ puis en descendant
    • Dès qu’il trouve un caractère entièrement contenu dans la silhouette, il remplace la zone par ce caractère
    • Grâce au tri, ce caractère est forcément le candidat avec le plus grand nombre de pixels blancs
  • Pour accélérer fortement le traitement, 171 bitmasks sont préparés, un pour chaque pixel d’une zone 9×19
    • Chaque bitmask représente l’ensemble des images de caractères ASCII ayant un pixel noir à cette coordonnée
    • Chaque bitmask contient 95 bits
    • Le bit 0 correspond au caractère espace, le bit 94 au caractère @
  • Pendant la conversion d’une zone, un accumulateur de 95 bits sert à restreindre progressivement l’ensemble des candidats ASCII possibles
    • Au départ, l’accumulateur est initialisé avec tous les bits à 1
    • Pour chaque pixel noir de la zone, on applique un AND bit à bit entre l’accumulateur courant et le bitmask de ce pixel
    • Cette opération élimine les images de caractères ayant un pixel blanc aux positions noires de la zone
  • Une fois toute la zone traitée, les bits à 1 restants dans l’accumulateur représentent les caractères candidats remplaçables
    • Comme les caractères sont triés, le nombre de zéros de tête de l’accumulateur donne l’indice de l’image de caractère ASCII ayant le plus de pixels blancs tout en restant entièrement dans la silhouette
    • À l’aide d’une bibliothèque, l’outil invoque rapidement l’instruction de calcul des zéros de tête du microprocesseur pour obtenir cette valeur

Optimisation de l’origine et association des couleurs

  • Lors du découpage de l’image source en matrice de zones rectangulaires, l’origine de la matrice influence le résultat
  • Pour optimiser le rendu, l’algorithme répète la conversion complète de l’image pour toutes les origines à coordonnées entières situées dans une zone de 9×19 pixels autour de l’origine de l’image
  • Pour absorber cette charge de calcul, le travail est réparti entre les processeurs logiques disponibles
  • Selon le réglage utilisateur, la palette de couleurs peut être limitée depuis les 8 premières couleurs ANSI standard jusqu’à l’ensemble complet des 256 couleurs ANSI étendues
  • Lors de la séparation de l’image source en plans de couleurs uniques, la formule de différence perceptuelle de couleur CIEDE2000, coûteuse en calcul, est utilisée pour trouver la couleur la plus proche dans la palette

Code source

1 commentaires

 
GN⁺ 2024-06-08
Avis sur Hacker News
  • Je pense que la page la plus cool de ce site est la galerie couleur : https://meatfighter.com/ascii-silhouettify/color-gallery.htm...

    • Le logo Wendy's est un peu flippant
    • Sans le logo Mastodon, cette page ne compte pas
    • Le logo Z est vraiment ingénieux
      Ça donne l’impression de regarder le design graphique d’icônes sous un autre angle
  • J’ai créé un outil similaire pour faire des sprites de jeu qu’on peut intégrer directement dans le code : https://memalign.github.io/m/pceimage/index.html
    Il fonctionne sur le web, et la sortie ASCII en couleur est aussi modifiable
    En revanche, pour obtenir un bon résultat, c’est un peu délicat : il faut désactiver manuellement le Wobble et ajuster la taille d’échantillonnage des pixels

    • C’est vraiment amusant et j’adore
      Si je peux suggérer quelque chose, ce serait bien d’avoir un mode qui supprime le tremblement, mais conserve le côté mignon obtenu en épaississant les formes et en arrondissant les coins
  • Si vous aimez l’art autour de l’ASCII, je pense que vous aimerez aussi cet outil d’ASCII animé qui transforme les GIF en ASCII : https://www.gifcii.fun
    Pour info, c’est moi qui l’ai fait

    • En tant que fan de GIF, c’est vraiment amusant
      Ce serait bien de pouvoir l’enregistrer somehow, par exemple l’exporter à nouveau en GIF ou en vidéo serait super
  • La version web ne va pas au bout dans les navigateurs basés sur Chromium, mais la version CLI fonctionne : https://meatfighter.com/ascii-silhouettify/spa/index.html#/
    En bonus, j’ai aussi fait un grand ASCII art qui ressemble au logo HN

  • Super travail, et ça me rappelle le Telnet Matrix en couleur :)
    Plus tard, j’ai aussi découvert https://ascii.theater/
    Il y a quelques années, j’avais fait quelque chose de similaire pour un convertisseur d’images destiné à un ordinateur rétro, en utilisant la police à chasse fixe de cet ordinateur et en appliquant aussi du dithering avant la conversion en caractères
    Parce que ça produisait des dégradés plus doux dans les photos : https://github.com/KodeMunkie/imagetozxspec/blob/master/src/...

  • « Ce qui a été, c’est ce qui sera ; ce qui s’est fait, c’est ce qui se fera. Il n’y a rien de nouveau sous le soleil. »
    Bien fait
    À l’époque, avec EBCDIC et ASCII, on utilisait la densité d’impression des caractères pour produire des bannières d’anniversaire et des dessins très similaires sur des imprimantes à bande en papier continu, puis plus tard sur des imprimantes matricielles

  • Je pense qu’il va y avoir pas mal de gens qui vont modifier /etc/motd ou /etc/issue aujourd’hui

  • J’ai essayé quelque chose de similaire avec une fonction ondulante animée en temps réel : https://piter-genuary2024.netlify.app/genuary9/

    • Je me demande si on pourrait créer quelque chose de bizarre qui commencerait comme une sortie standard de tail de logs, puis mélangerait progressivement des motifs de plus en plus visibles, jusqu’à faire apparaître un visage effrayant au milieu du texte
  • Encore npm
    Le projet est excellent, mais je ne comprends pas pourquoi il faut absolument faire comme ça
    Je me demande où est passée la méthode d’installation normale

    • Je serais curieux de savoir quelle alternative tu proposes
      NPM fonctionne partout de la même façon, et aucun gestionnaire de paquets n’est aussi largement utilisé sur autant de plateformes que NPM
    • Si tu expliques ce que tu entends ici par « installation normale », je pourrai te dire quels sont les problèmes de cette méthode
    • Pas besoin de l’installer non plus
      Il suffit de l’exécuter avec npx
    • Oui, je me demande aussi ce qu’est devenue la méthode d’installation normale, ou si elle a jamais vraiment existé
      Configurer autrement prend des heures et devient vite le bazar, donc dans mes dépôts CLI j’utilise des npm/yarn link un peu partout
      Je développe même des scripts Python avec nodemon main.py, et parfois j’ai l’impression que seuls les gens de Node savent ce qu’il faut
  • Malgré tout, je pense que je continuerai à utiliser https://asciiflow.com/# plutôt que Figma