Comment les applications de coloriage stockent les contours
Ni tracé vectoriel, ni pot de peinture. Une seconde image, jamais affichée, où la valeur de chaque pixel est un numéro de zone — plus une minuscule bande de palette et un petit programme exécuté par la carte graphique.
On imagine volontiers que le dessin affiché par une application de coloriage est un tracé, une suite de courbes que le programme parcourt pour savoir où s’arrête une zone. Ce n’est presque jamais le cas. La solution retenue dans ce genre de logiciel est plus simple, plus brutale et beaucoup plus rapide : une seconde image, invisible, dans laquelle la valeur de chaque pixel n’est pas une couleur mais un numéro de zone.
Le détour technique vaut la peine, parce que ce choix explique une bonne partie de ce que l’on observe à l’usage : la couleur qui apparaît sans le moindre délai, les contours qui restent nets à tous les grossissements, les chiffres qui disparaissent quand on s’éloigne, et le fait qu’un remplissage ne bave jamais.
Pourquoi pas des vecteurs
Un format vectoriel décrit des contours par des courbes. Pour savoir dans quelle zone se trouve un point, il faudrait tester ce point contre les contours, un par un, jusqu’à trouver celui qui l’enferme. Sur une image découpée en plusieurs milliers de zones, l’opération est coûteuse, et elle devrait être refaite à chaque toucher.
Le vectoriel pose un second problème, plus sournois. Deux contours voisins ne se referment pas exactement au même endroit une fois convertis en pixels : il subsiste des interstices d’un pixel, invisibles à l’œil mais suffisants pour qu’un algorithme hésite. Une carte de zones en pixels ne peut pas avoir d’interstice, par construction : chaque pixel appartient à une zone et à une seule.
Pourquoi pas un pot de peinture
L’autre intuition est le remplissage par diffusion, le fameux pot de peinture des éditeurs d’images : on part du pixel touché et on contamine de proche en proche jusqu’à rencontrer une frontière sombre. Cette méthode a ici trois défauts rédhibitoires.
Son coût dépend de la surface à remplir, ce qui donne une réactivité irrégulière. Elle échoue si le contour comporte un trou d’un seul pixel, et la couleur s’échappe alors dans toute l’image. Enfin, et c’est le plus grave, elle ne dit pas quel numéro porte la zone : elle sait où s’arrêter, pas ce qu’elle vient de remplir.
La carte d’index
La solution effectivement employée consiste à livrer deux images de mêmes dimensions. La première est celle que l’on voit : les traits, le fond, les chiffres. La seconde n’est jamais affichée ; c’est une carte d’index, où la valeur d’un pixel est un identifiant de zone. Savoir sur quelle zone le doigt s’est posé revient alors à lire une seule valeur, à des coordonnées connues. C’est une opération à coût constant, quelle que soit la complexité du motif.
Comme un canal d’image ne code que 256 valeurs, un identifiant est réparti sur plusieurs canaux : le rouge porte les huit bits de poids faible, le vert les huit suivants, ce qui autorise plusieurs dizaines de milliers de zones distinctes. Le canal de transparence est en général évité pour cet usage, parce que les chaînes de rendu ont la mauvaise habitude de le prémultiplier ou de le convertir, ce qui réécrirait silencieusement les identifiants.
Cette carte doit être stockée sans compression destructrice et sans le moindre lissage. Un format qui calcule des moyennes entre pixels voisins inventerait des identifiants qui n’existent pas : une zone 41 collée à une zone 63 produirait le long de la frontière une frange de zones 52 parfaitement imaginaires.
La bande de palette et le tableau d’état
Deux petits objets complètent le dispositif. Le premier est une bande de palette : une image minuscule, souvent une seule ligne de quelques pixels, où le pixel numéro trois contient exactement la couleur du numéro trois. Le second est un tableau d’état, un octet par zone, qui dit si la zone est remplie et avec quelle couleur.
L’ensemble tient dans très peu de mémoire. Une image de quatre mille zones se décrit avec quatre mille octets d’état, soit moins qu’une seule ligne de l’image visible. C’est pour cette raison qu’une progression peut être conservée sans rien peser, et qu’elle est restituée sans qu’aucune image ait jamais été enregistrée.
Le rôle de la carte graphique
Le dernier morceau est un petit programme exécuté par le processeur graphique, un shader, pour chaque pixel affiché. Il lit l’identifiant de zone dans la carte d’index, consulte le tableau d’état, puis décide : si la zone est remplie, il va chercher la teinte correspondante dans la bande de palette ; sinon il affiche le fond, le trait et éventuellement le chiffre. Rien n’est redessiné, rien n’est recalculé par le processeur principal.
C’est ce qui explique l’instantanéité du remplissage. Poser une couleur ne repeint rien du tout : cela modifie un octet dans le tableau d’état, et l’image suivante est simplement produite autrement. C’est aussi ce qui rend l’agrandissement fluide, puisque zoomer ne fait que changer les coordonnées lues dans la carte d’index.
Ce que cette architecture explique
- Les bords ne sont jamais adoucis : un pixel de la carte d’index doit appartenir à une zone et à une seule, et une valeur intermédiaire n’aurait aucun sens.
- Les chiffres disparaissent quand on s’éloigne : ils sont dessinés à la volée à partir d’une position et d’une taille, et en dessous d’une certaine hauteur en pixels ils cessent d’être lisibles avant de cesser d’être utiles.
- Un toucher peut désigner la mauvaise zone : la lecture est exacte, mais elle porte sur un point unique alors que le doigt en recouvre des centaines.
- Deux numéros peuvent porter des teintes presque identiques : la bande de palette n’a aucune contrainte de distinguabilité, elle reproduit les couleurs de l’image d’origine.
Rien de tout cela n’est spectaculaire, et c’est précisément l’intérêt : le procédé est ancien, économe et prévisible. La partie réellement difficile se situe en amont, dans la fabrication de la carte d’index — découper une photographie en zones assez grandes pour être remplies, assez petites pour que le résultat ressemble encore à quelque chose, et placer les frontières là où l’œil accepte une rupture.
Questions fréquentes
Pourquoi ne pas simplement utiliser un remplissage automatique comme dans un éditeur d’images ?
Parce que son coût dépend de la taille de la zone, qu’un trou d’un seul pixel dans le contour laisse la couleur se répandre partout, et surtout parce qu’il ne sait pas quel numéro porte la zone remplie. Une carte d’index donne l’identifiant en une seule lecture, immédiatement et sans risque.
Combien de zones une image peut-elle contenir avec ce système ?
En répartissant l’identifiant sur deux canaux de huit bits, on dispose de plusieurs dizaines de milliers de valeurs, très au-delà de ce qu’un motif utilisable contient. La limite pratique n’est pas technique : c’est la taille minimale d’une zone que l’on peut viser avec un doigt et dans laquelle un chiffre reste lisible.
Pourquoi les contours restent-ils nets quand on agrandit beaucoup ?
Parce que le trait et les chiffres sont redessinés à l’échelle d’affichage par le processeur graphique plutôt que d’être agrandis comme une photographie. La carte d’index, elle, ne sert qu’à savoir quelle zone occupe quel pixel, ce qui reste exact quel que soit le grossissement.
Essayer sur une vraie toile
Numbrush est un coloriage par numéros pour adultes : mandalas, rosaces et entrelacs géométriques, douze couleurs par planche, une loupe pour les endroits étroits, et aucune sanction si le doigt tombe à côté. Gratuit, hors ligne, sans publicité ni compte.