L'art non contextuel

Posté par  . Édité par Benoît Sibaud. Modéré par Pierre Jarillon. Licence CC By‑SA.
28
2
août
2026
Graphisme/photo

Traduit de l’allemand ; publié à l’origine sur gnulinux.ch.

Cet article présente le logiciel Context Free art, qui permet de « programmer » des images à l’aide de quelques commandes simples.

Le contenu du site Context Free Art est sous licence Creative Commons Attribution-Share Alike 2.5 et le logiciel sous GPLv2.

Image d’une fractale dessinée avec Context Free art

Sommaire

Installation et utilisation

Sous Ubuntu/Debian, on installe le programme avec sudo apt-get install contextfree. Pour les autres distributions, une notice d’installation est disponible sur le site du projet. On peut aussi utiliser Distrobox pour faire tourner Debian/Ubuntu dans un conteneur sous une autre distribution Linux.

Sous Windows, il existe une interface graphique. Sous Linux, en revanche, on exécute le programme dans le terminal avec cfdg fichier_entree.txt fichier_sortie.png.

Ma configuration sous Kubuntu ressemble à ceci :

  • En haut à gauche, un terminal dans lequel j’exécute cfdg fichier_entree.txt fichier_sortie.png pour générer l’image.
  • En bas à gauche, un éditeur avec le fichier texte à partir duquel l’image est générée.
  • À droite, j’ouvre l’image produite. J’utilise Okular pour cela, car il recharge automatiquement une image mise à jour.

Capture d’écran d’un bureau. En haut à gauche un terminal, en bas à gauche un éditeur de texte avec un fichier source Context Free ouvert, et à droite l’image de sortie correspondante : un cercle gris à droite d’un cercle noir

Avec un peu de « magie Linux », on peut sûrement faire en sorte que cfdg soit relancé automatiquement à chaque enregistrement du fichier, et ainsi se passer du terminal. Cela dit, la génération d’une image à partir du code peut être relativement longue ; il est donc parfois préférable de pouvoir initier et arrêter la génération manuellement.

Syntaxe

Une documentation détaillée du langage se trouve dans le wiki du projet. Nous avons déjà rencontré quelques éléments de syntaxe dans l’image ci-dessus :

startshape FORME // commence par la forme nommée « FORME »

shape FORME { // Quand tu dessines la forme FORME
CIRCLE []  // alors dessine un cercle
CIRCLE [x 1 brightness 0.5] // Dessine un cercle décalé horizontalement
                            // de 1 et de luminosité 0.5
}

Structure d’un fichier Context Free

  • Le fichier devrait toujours commencer par le choix d’une forme de départ : startshape NOM_FORME_DEPART. Cette forme doit ensuite être décrite.
  • La description d’une forme utilise la syntaxe shape NOM { … }, où les accolades contiennent une consigne de dessin.
  • Une consigne de dessin est une suite de formes (dans l’exemple ci-dessus, deux cercles CIRCLE), modifiées par les instructions placées entre crochets […].
  • Une modification se compose typiquement d’une commande (x ou brightness) suivie d’une ou de plusieurs valeurs numériques.

Formes de base et modifications

Les formes de base disponibles sont CIRCLE, SQUARE et TRIANGLE. Dans cet article, nous utiliserons quelques-unes des modifications suivantes (les points d’interrogation représentent des nombres à insérer) :

  • x ? pour un décalage horizontal vers la droite de ?. Une valeur négative décale vers la gauche. De façon analogue, y ? pour les décalages verticaux.
  • size ? pour mettre à l’échelle d’un facteur ?. Par exemple size 0.5 pour réduire de moitié la taille d’une forme.
  • rotate ? pour tourner une forme de ? degrés.
  • Pour les couleurs, le programme utilise l'espace colorimétrique TSV (teinte, saturation, valeur), aussi appelé HSB ou HSV en anglais. On contrôle ainsi la couleur avec hue ? (rotation à travers les couleurs du cercle chromatique), sat ? (saturation de la couleur) et brightness ? (luminosité).

Récursion

L’un des grands atouts de Context Free est qu’une forme peut dessiner une copie (éventuellement modifiée) d’elle-même. En informatique, ce procédé s’appelle la récursion. Voici un petit exemple :

startshape MAFORME

shape MAFORME {
SQUARE [brightness 1 sat 1] // Dessine un carré (pleinement saturé et lumineux)
MAFORME [x 1.1 rotate 20 size 0.99 hue 10] // Dessine une copie de toi-même (décalée,
                                            // tournée, réduite et de teinte modifiée)
}

Une spirale colorée composée de carrés de plus en plus petits

Lorsqu’on utilise la récursion, il faut faire un peu attention : en principe, le programme pourrait tourner indéfiniment et dessiner toujours plus de copies de la forme. Pour éviter cela, nous avons intégré ci-dessus une réduction de taille : lorsque les formes deviennent trop petites, Context Free interrompt le travail et cesse de les dessiner.

Hasard

Un autre atout de Context Free est qu’il permet d’effectuer des variations aléatoires sur les figures générées. Dans l’exemple suivant, le hasard est introduit de deux manières :

startshape FORET

shape FORET {
ARBRE []
ARBRE [x 50]
ARBRE [x 100]
}

shape ARBRE // À chaque dessin d’ARBRE, l’une des deux
            // règles (« rules ») est choisie au hasard (de façon pondérée).
rule 0.97 {
CIRCLE []
ARBRE [y 0.5 size 0.99 rotate (rand(-4,4))]
// Ici ARBRE est tourné d’une valeur aléatoire comprise entre -4 et 4
}

rule 0.03 {
ARBRE [rotate 20]
ARBRE [rotate -20]
}

Les nombres après rule sont des poids : dans 97 % des cas, l’arbre continue de pousser tout droit (première règle), et dans 3 % des cas seulement, il se divise en deux branches (seconde règle).

Trois silhouettes d’arbres différentes côte à côte

Et bien plus encore

Context Free possède de nombreuses autres fonctionnalités. Outre la documentation dans le wiki du projet, il existe aussi une galerie contenant de nombreuses images à la fois esthétiques et intrigantes.

Aspects mathématiques

Grammaires non contextuelles

Le programme s’appelle Context Free (« sans contexte ») parce que la syntaxe avec laquelle les images sont créées est une grammaire non contextuelle au sens des langages formels. Intuitivement, cela signifie que les consignes de dessin figurant dans le programme ne dépendent jamais de ce qui a déjà été dessiné autour. Par exemple, il n’y a aucun moyen de formuler quelque chose comme : « dessine un cercle s’il n’y a pas de cercle à proximité ».

Fractales

Grâce à la possibilité de faire de la récursion, Context Free est un excellent outil pour dessiner des fractales. Une fractale est une image dont les fragments ressemblent approximativement à l’image entière. En gros, si l’on n’observe qu’un petit morceau des arbres ci-dessus, il est difficile de savoir avec certitude si l’on se trouve sur le tronc de l’arbre, sur une branche ou sur une ramification. Dans la vie quotidienne, nous rencontrons régulièrement des fractales, par exemple au marché au rayon des légumes avec le chou romanesco. La galerie de Context Free contient de nombreuses fractales ; celle-ci m’a particulièrement plu (et elle a été créée avec le même code que la première image de cet article).

Aller plus loin

  • # Merci pour la news

    Posté par  . Évalué à 1 (+0/-0).

    ça donne envie d'essayer, je lisais l'autre jour le blog de Xah Lee et certaines sections sont un peu dans le même domaine, par exemple celle dédiée au langage Wolfram et aux logiciels de "tiling".

    Je trouve fascinant de créer des images à partir de texte!

  • # Le zéro-pouce ?

    Posté par  (site web personnel, Mastodon) . Évalué à 3 (+2/-0). Dernière modification le 04 août 2026 à 14:24.

    Belle découverte. Le projet est ancien et je ne le connaissais pas.

    Quelle est le critère pour arrêter la récursion ? la résolution de l’écran ? les capacités de la machine ?

    C’est sympa, ça évite l’effondrement, ce n’est pas très pédagogique pour comprendre le principe de la récursivité en informatique mais Context Free permet aussi de programmer l'arrêt.

    Dans Ma Thémagie - recueil entrecroisé d’études littéraires, scientifiques et artistiques de Douglas Hofstadter on trouve une série d’articles sur Lisp et sur la beauté de la récursivité. L’auteur décrit le vilain porc-et/ou-pic de Glazonquie dont les piquants sont des porc-et/ou-pic de taille réduite. La régression infinie de l’animal est évitée par l’existence du porc-et/ou-pic de dimension minimale, le zéro-pouce, qui bizarrement est dépourvu de piquants…

    Titre de l’image

    • [^] # Re: Le zéro-pouce ?

      Posté par  (site web personnel) . Évalué à 5 (+3/-0).

      Je viens de tester, tu as une option pour ça : CF::MinimumSize

      C’est intéressant, j’aime beaucoup le côté récursif dans la définition.

      Voici ma petite contribution pour un logo pour représenter un outil de transformation de données :

      startshape FORME
      
      CF::Background = [brightness -1]
      CF::MinimumSize = 3
      
      path ARROW {
          MOVETO(0.0, 0.5)
          LINETO(1.0, 0.0)
          LINETO(0.0,-0.5)
          CLOSEPOLY()
          FILL()[]
      }
      
      
      
      shape SOURCE
      rule {
          SOURCE [hue 5 brightness rand(-0.5, 0) size .8  x -1.25 y -1]
          SQUARE [ size .5 x -1 y -1]
          SOURCE [hue 5 brightness rand(-0.5, 0) size .8 x -1.25 y 1]
          SQUARE [ size .5 x -1 y 1]
          SQUARE [size .1 1.5 x -1 ]
          SQUARE [size 0.5 .1 x -.7]
          ARROW [ size .5 x -0.5 ]
      }
      rule {
          SOURCE [hue 15 size .5 x -1.25 alpha 20]
          SQUARE [ size .5 .1 x -0.5 y 0]
          ARROW [ size .5 x -0.5 ]
          SQUARE [ size .5 x -1 ]
      }
      
      shape FORME {
          SQUARE [ brightness 1 ]
          SOURCE [hue 20 saturation 1 brightness 1 size .8]
          SOURCE [hue 20 saturation 1 brightness 1 size .8]
      
      }
      

      Et le résultat:
      Chaine de transformation

      Le seul point qui me gêne est qu’il n’est pas possible de définir une graine dans le fichier lui même (cela peut être fait en ligne de commande par contre, ici avec --variation=123456)

      J’aime beaucoup !

      • [^] # Re: Le zéro-pouce ?

        Posté par  (site web personnel, Mastodon) . Évalué à 2 (+1/-0).

        La gestion de la graine est effectivement reportée sur l'interface.

        La version Mac de CF possède une interface intégrée avec éditeur, visualiseur, fenêtre de logs et champ des « variations » éditable/sélectable pour retrouver le même « hasard » et donc la même image produite.

        Titre de l’image

        • [^] # Re: Le zéro-pouce ?

          Posté par  (site web personnel) . Évalué à 2 (+0/-0).

          Merci du complément, je vais regarder si le code n’est pas trop compliqué pour proposer l’option.

          La vue que tu présentes me donne des souvenirs de povray sous windows. J’ai l’impression de retrouver la même coloration syntaxique avec ce mélange de vert et de violet !

          • [^] # Re: Le zéro-pouce ?

            Posté par  (site web personnel) . Évalué à 2 (+0/-0).

            J’ai l’impression de retrouver la même coloration syntaxique avec ce mélange de vert et de violet !

            oh bah si c'est ça qui te manque, tu peux retrouver la syntaxe Markdown de code avec coloration syntaxique qu'a des couettes (comme Sheila) sur https://pygments.org/languages/

            un petit exemple avec ```tcl (il y a sans doute mieux, spa génial pour les commentaires par exemple :/) :

            rule {
                SOURCE [hue 15 size .5 x -1.25 alpha 20]
                SQUARE [ size .5 .1 x -0.5 y 0]
                ARROW [ size .5 x -0.5 ]
                SQUARE [ size .5 x -1 ]
            }
            
            shape FORME {
                SQUARE [ brightness 1 ]
                SOURCE [hue 20 saturation 1 brightness 1 size .8]
                SOURCE [hue 20 saturation 1 brightness 1 size .8]
            
            }
    • [^] # Re: Le zéro-pouce ?

      Posté par  (site web personnel, Mastodon) . Évalué à 4 (+2/-0).

      Ah tiens, les exemples m’ont rappelé aussi des souvenir de Lisp, mais aussi de Logo (dont des bibliothèques Turbo Pascal puis Python ont repris la tortue entre autres) et de Forth (pour le côté Scratch de combinaison de briques)…

      “It is seldom that liberty of any kind is lost all at once.” ― David Hume

      • [^] # Re: Le zéro-pouce ?

        Posté par  (site web personnel, Mastodon) . Évalué à 2 (+1/-0).

        Oui, c'était la récursivité qui m'avait rappelé Lisp, et bizarrement je n'avait pas fait le rapprochement avec Logo et sa tortue (que j'ai aussi abondamment pratiqué dans les années 80).

        Ce qui fait l'originalité de Logo a été abondamment théorisé et illustré par Seymour Papert dans Jaillissement de l'esprit. Ordinateurs et apprentissage c'est, entre autres, le dialogue constant avec le système pour construire des micro-mondes et la possibilité de se mettre physiquement à la place de la tortue.

        • [^] # Re: Le zéro-pouce ?

          Posté par  (site web personnel, Mastodon) . Évalué à 2 (+0/-0).

          C’est un peu la syntaxe qui m’y a fait penser. :-)
          Ainsi, si je reprends le premier exemple…

          La première ligne, startsharpe FORME se traduirait juste par FORME (ou montre FORME s’il s’agit d’un résultat de calcul et non d’un dessin) ;
          puis la définition qui suit :

          shape FORME {
          CIRCLE []
          CIRCLE [x 1 brightness 0.5]
          }

          …se traduirait en logo francisé, mais défini préalablement à l’appel, par

          pour FORME
            CIRCLE
            CIRCLE 1 0.5
          fin
          

          Par contre, il faut avoir créé les formes de base, ce qui se fait aisément (et j’imagine que le TRIANGLE ici est équilatéral ?).

          L'autre truc qui m’a fait penser à ce langage, ce sont les crochets et les modifications :

          cfdg logo
          x ? av ? (tortue regardant vers la droite)
          x -? re ? (tortue regardant vers la droite)
          y ? av ? ou avance ? (tortue regardant vers le haut)
          y -? re ? ou recule ? (tortue regardant vers le haut)
          rotate ? td ? ou droite ? (tortue orientée à 0°)
          rotate -? tg ? ou gauche ? (tortue orientée à 0°)
          size ? (je sèche pour celui-ci)

          …les modifications dans une certaine limite (comme indiqué entre parenthèses) et puis la couleur, si je ne me rappelle bien était géré avec une palette numéroté, et non pas spécifiée sous forme HSB/TSL
          L’exemple de récursion donné en exemple :

          shape MAFORME {
          SQUARE [brightness 1 sat 1]
          MAFORME [x 1.1 rotate 20 size 0.99 hue 10]
          }

          …ressemblerait en logo à quelque chose comme :

          pour MAFORME :taille :couleur
            fcc :couleur
            SQUARE :taille
            avance 1.1
            droite 20
            repete 1 [
              MAFORME [retourne produit :taille 0.99]
                      [retourne somme :couleur + 1]
            ]
          fin
          

          Logo reprend les aspects fonctionnel et orienté object réflexif de Lisp ;-) mais laisse les parenthèses (je me souviens avoir même lu que c’est un « Lisp sans parenthèse » et de me dire « mais ils ont mis des crochets » haha)… et a une récursion toujours terminale. Puis il va influencer à son tour (en tout cas j’y retrouve des clins d’œil) : Smalltalk (plus Lisp directement et Simula), Scratch (qui à son tour va, avec Scheme, influencer BYOB/Snap!), Rebol (influencé aussi par Forth et Self), etc.

          Mais bon, on retrouve nombre des aspects de CFDG dans divers langages textuels de dessin non contextuel ; mais il y a un petit plus par rapport à ceux que je connais : les rules natifs…! (ou alors ça ne m’avait pas marqué ?)

          “It is seldom that liberty of any kind is lost all at once.” ― David Hume

          • [^] # Re: Le zéro-pouce ?

            Posté par  (site web personnel, Mastodon) . Évalué à 2 (+1/-0).

            La force et la simplicité de la tortue Logo est de s'affranchir des coordonnées cartésiennes locales et absolues, pour ne garder que l'orientation. À partir de là tu avances et tu tournes ; pour le dessin, la métaphore est celle du pinceau qui se lève et s’abaisse, et change de forme aussi. Dans ton exemple size correspond donc à la taille du pinceau ; c'est différent que de jongler avec des formes comme CF (mais on peut aussi le faire en les définissant préalablement).

            C'est important, car tu peux commencer à programmer sans autre repère que le tiens, te mettre à la place de la tortue pour lui faire faire ce que tu veux.

            La tare de Scratch c'est d'arriver avec un repère cartésien et un personnage vertical vu de face, le chat. J’ai vu des enfants et les animateurs / animatrices se prendre la tête sur des projets avec des cosinus et des sinus, alors qu’ils pouvaient faire autrement et simplement (à la Logo). De ce point de vu Snap! (clone de Scratch (du MIT) proposé par Berkeley pour faire de l’informatique…) est plus malin, son personnage par défaut est un triangle vu du dessus. A noter aussi qu’on retrouve dans Snap! les listes et les arbres comme structures de données et surtout la possibilité de redéfinir de nouveaux blocs (ce qui a tardé à être implémenté en Scratch).

            Dans la foulée, à ta liste, j’ajoute Metapost et la variante Squeak de Smalltak et ses exotiques Etoys.

            Titre de l’image

            Context Free se présente d'abord comme un outil ouvert, pragmatique et efficace pour produire des images (y compris des séquences).

  • # Et par rapport à TikZ ?

    Posté par  (site web personnel) . Évalué à 5 (+5/-0).

    Professeur de Mathématiques et utilisateur régulier de LaTeX/TikZ, je découvre Context Free Art avec intérêt.

    Le principe me semble particulièrement riche du point de vue mathématique : répétitions, rotations, homothéties, variations aléatoires et récursivité. Cela paraît assez accessible pour faire émerger des images complexes à partir de quelques règles simples.

    Je me demande cependant où se situe, dans la pratique, la frontière avec TikZ/PGF. TikZ permet aussi de programmer des motifs, d’utiliser des boucles, des transformations et même de construire des figures récursives. Mais j’ai l’impression que la philosophie est inversée : avec TikZ, on programme surtout une figure destinée à prendre place dans un document ; ici, l’image générative semble être le cœur même du langage.

    Pour les personnes qui ont utilisé les deux : est-ce principalement une différence d’ergonomie et de philosophie, ou Context Free Art permet-il des constructions qui deviendraient rapidement pénibles à écrire en TikZ ?

    Et peut-on exporter facilement le résultat dans un format vectoriel afin de l’intégrer ensuite dans un document LaTeX ?

    • [^] # Re: Et par rapport à TikZ ?

      Posté par  (site web personnel) . Évalué à 4 (+2/-0).

      Oui, tu as une sortie possible en SVG. Il est également possible de générer du json, je n’ai pas l’impression qu’il s’agisse de l’arbre des objets dessinés.

      Le SVG a besoin par contre d’être retouché avant d’être intégré dans un autre projet :

      • l’appli ne semble pas redéfinir la zone d’affichage si des éléments s’échappent (par exemple à cause d’une récursion qui se prolonge)
      • la couleur de fond ne semble pas être prise en compte (j’ai eu besoin de la redéfinir ensuite via inkscape)

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.