DESSINS PIXEL PAR PIXEL AVEC TKINTER

1 - Pixels et couleurs

a) Où l'on ouvre une fenêtre et l'on peint quelques pixels

from tkinter     import Tk, Canvas
from PIL.Image   import new
from PIL.ImageTk import PhotoImage


WIDTH = 600 ; HEIGHT = 600

def Afficher(Dessin) :

    F = Tk() ; F.title("Dessin")
    D = Canvas(F, width = WIDTH, height = HEIGHT)
    D.pack()

    PhImg_Dessin = PhotoImage(Dessin)
    D.create_image((1 + WIDTH // 2 , 1 + HEIGHT // 2), image = PhImg_Dessin)

    F.mainloop()


def CréerDessin() :
    return new("RGB", (WIDTH , HEIGHT), "white")


?

>>> Afficher(CréerDessin())


from random import randint as EntAléa

def FlouArtistique() :

    Dessin = CréerDessin()

    for px in range(0, WIDTH) :
        for py in range(0, HEIGHT) :

            r = EntAléa(0, 255) ; g = EntAléa(0, 255) ; b = EntAléa(0, 255)
            Dessin.putpixel( (px, py), (r, g, b) )

    return Dessin


?

>>> Afficher(FlouArtistique())


b) Un dessin célèbre : les trois couleurs primaires de la synthèse additive

On souhaite produire le dessin ci-dessous.

La zone de dessin qu'on utilise est de dimensions 600×600, on choisit donc des disques de rayon 150 et les trois centres \(\mathrm{A}(400, 300)\), \(\mathrm{B}(230, 200)\) et \(\mathrm{C}(230, 400)\) (respectivement pour le rouge, le vert et le bleu).

Rayon = 150
xA = 400 ; yA = 300
xB = 230 ; yB = 200
xC = 230 ; yC = 400

Pour obtenir le mélange des couleurs, l'astuce est la suivante : on choisit indépendamment les valeurs de rouge, de vert et de bleu en fonction de la position du pixel. On part d'une couleur (le noir) représentée par une liste Couleur à trois éléments (on ne peut pas utiliser un triplet, qui serait immuable) et pour chacun des trois centres \((x, y)\) associé à chacune des trois composantes \(i = 0, 1, 2\) on modifie la composante \(i\) de la liste Couleur si l'on se trouve suffisamment proche du centre.

def SynthèseAdditive() :

    Dessin = CréerDessin()

    for px in range(0, WIDTH) :
        for py in range(0, HEIGHT) :

            Couleur = [0, 0, 0]
            for (x, y, i) in [(xA, yA, 0), (xB, yB, 1), (xC, yC, 2)] :
                if (px - x)**2 + (py - y)**2 <= Rayon**2 :
                    Couleur[i] = 255

            Dessin.putpixel( (px, py), tuple(Couleur) )

    return Dessin

On obtient alors le dessin ci-dessus avec cette commande.

>>> Afficher(SynthèseAdditive())

c) Plus de couleurs : le cercle chromatique

Soit \((r, g, b)\) une couleur. On définit sa saturation comme l'amplitude des trois composantes, à savoir \[ \mathrm{sat}(r, g, b) = \mathrm{max}(r, g, b) - \mathrm{min}(r, g, b). \] Ainsi la saturation est nulle si et seulement si les trois composantes sont égales (donc la couleur est une nuance de gris, chère à E. L. James), et elle est maximale si et seulement si l'une des composantes est à \(255\) et une autre à \(0\) (la troisième faisant ce qu'elle veut). Une telle couleur est dite saturée, et on va voir dans un instant que cela correspond aux couleurs vives. Inversement, plus la saturation est faible et plus la couleur est terne.
    Voyons comment construire toutes les couleurs saturées. On en associe une à chaque réel \(\theta\) selon le procédé suivant. On définit trois fonctions \[ \mathrm{R}, \mathrm{G}, \mathrm{B} : \mathbf{R} \rightarrow \left\{0\,;\,1\,;\,255\right\} \] \(2\pi\)-périodiques, dont voici les courbes (évidemment, selon les conventions pour les codes RGB, le domaine d'arrivée peut changer, par exemple \([0\,;\,1]\) pour MatPlotLib).


2 - Utilisation des coordonnées géométriques


?

def ?
?

def ?
?


3 - Lignes de niveau et courbes implicites


?

def ?
?

def ?
?