Créer une image pixel par pixel
Une image est une grille de triplets (R, V, B) : un programme peut donc la fabriquer, pixel par pixel. C'est ce qu'on fait ici, et au passage on apprend un geste nouveau : parcourir toute une grille avec une boucle dans une boucle.
Cours ici, exercices sur Capytale
Cette page est le cours. Les exercices sont sur Capytale.
Une image vide
Pour manipuler des images, on va chercher le modèle Image dans la boîte à outils PIL, comme on allait chercher Turtle dans turtle :
Image.new("RGB", (300, 200))crée une image de 300 pixels de large sur 200 de haut, en couleurs RVB, et on la range dans la variableimg. Tous ses pixels démarrent à(0, 0, 0): l'image est noire.- Sur Capytale, écrire
imgseul en fin de cellule affiche l'image.
Les coordonnées d'un pixel
Chaque pixel a une adresse (x, y) : x compte les colonnes vers la droite, y compte les lignes vers le bas. Le pixel (0, 0) est en haut à gauche, comme le point de départ de nos tracés sur la grille de la première séance.
Attention au sens de y : il descend. Et les coordonnées vont de 0 à largeur - 1 (ou hauteur - 1) : dans notre image de 300 sur 200, le pixel en bas à droite est (299, 199).
Colorier un pixel
Pour changer la couleur d'un pixel, on parle à l'image avec la notation pointée, comme on parlait à la tortue :
Ça se lit : « img, mets le pixel (150, 100) en rouge ». putpixel reçoit deux choses : les coordonnées du pixel, puis son nouveau triplet de couleur.
Un pixel seul, c'est un point minuscule. Pour dessiner quelque chose de visible, il faut en colorier beaucoup : autrement dit, boucler.
Une ligne de pixels
Pour tracer une ligne horizontale rouge, on fait varier x sur toutes les colonnes, à y fixé. C'est la boucle qu'on connaît, avec ses deux bornes :
from PIL import Image
img = Image.new("RGB", (300, 200))
for x in range(0, 300):
img.putpixel((x, 100), (255, 0, 0))
img
for x in range(0, 300): parcourt l'intervalle des colonnes : x vaut 0, puis 1, puis 2… jusqu'à 299. À chaque tour, on colorie le pixel (x, 100) : la ligne 100 devient rouge d'un bord à l'autre.
Toute l'image : une boucle dans la boucle
Et pour colorier tous les pixels ? Pense à la façon dont tu lis un texte : tu lis la première ligne mot par mot, puis tu passes à la ligne suivante et tu recommences. Pour une image c'est pareil : pour chaque ligne, parcourir toutes les colonnes.
En Python, ça s'écrit avec une boucle à l'intérieur d'une autre. On dit que les boucles sont imbriquées :
from PIL import Image
img = Image.new("RGB", (300, 200))
for y in range(0, 200):
for x in range(0, 300):
img.putpixel((x, y), (0, 0, 255))
img
Lis-le comme du texte : pour chaque ligne y (de 0 à 199), on parcourt toutes les colonnes x (de 0 à 299) et on colorie le pixel (x, y). Ici, tout en bleu : 200 × 300 = 60 000 pixels coloriés par 5 lignes de programme.
L'indentation, toujours elle
La boucle sur x est indentée sous la boucle sur y : elle est refaite en entier à chaque ligne. Et le putpixel, indenté deux fois, est dans les deux boucles : il est exécuté 60 000 fois.
La couleur peut dépendre de la position
Tout l'intérêt d'avoir x et y sous la main, c'est que la couleur peut se calculer à partir d'eux. Regarde :
from PIL import Image
img = Image.new("RGB", (256, 100))
for y in range(0, 100):
for x in range(0, 256):
img.putpixel((x, y), (x, 0, 0))
img
Le rouge du pixel vaut x : 0 tout à gauche (noir), 255 tout à droite (rouge vif). Résultat : un dégradé du noir au rouge, sans écrire un seul triplet à la main. C'est la même idée que la spirale : une valeur qui change au fil de la boucle.
Ce qu'on retient
Image.new("RGB", (largeur, hauteur))crée une image ;img.putpixel((x, y), (r, v, b))colorie un pixel (notation pointée : on parle à l'image).- Un pixel a des coordonnées
(x, y): origine en haut à gauche,xvers la droite,yvers le bas, de0àlargeur - 1ethauteur - 1. - Pour traiter toute l'image, on imbrique deux boucles : pour chaque ligne
y, parcourir toutes les colonnesx, comme on lit un texte. - La couleur peut se calculer à partir de
xety: c'est ce qui permet dégradés et motifs. - Le cours est ici ; on s'entraîne sur Capytale.
Et ensuite
Créer des images, c'est bien ; transformer une vraie photo, c'est mieux. À la prochaine séance, on lit les pixels d'une photo et on programme nos premiers filtres : noir et blanc, négatif.