Le module PIL de python permet de manipuler des images.
Avec python 3 on doit installer le package Pillow (il est installé par défaut avec Anaconda)
pip install Pillow
Pour charger une image on procède ainsi :
from PIL import Image
img = Image.open('logo.png')
On peut alors visualiser l'image en utilsant show()
:
img.show() # Utilise le logiciel associé du système d'exploitation, peut ne pas s'effectuer selon les droits de l'utilisateur
img # plus direct dans la console, on utilise cette technique dans la suite de la présentation
On peut accéder aux dimensions d'une image à l'aide de size
:
largeur, hauteur = img.size
print(largeur)
print(hauteur)
Pour créer une image on procède ainsi :
new_img = Image.new("RGB", (400, 300), "red")
new_img
L'instruction précédente crée ainsi une image :
Pour sauvegarder une image on utilise save('nom_du_fichier.format')
:
new_img.save('nouvelle_image.png')
Une fois une image ouverte, il est possible de la modifier rapidement.
Chacune des commandes ci-dessous renvoie une image. On peut donc créer une nouvelle variable afin de la stocker en faisant par exemple img_rotation = img.rotate(45)
img = img.resize((largeur//4,hauteur//4))
img
img.rotate(45)
img.transpose(Image.FLIP_LEFT_RIGHT)
Une image matricielle a pour structure un tableau de pixels (en mathématiques, une matrice est un tableau de nombres).
Chaque pixel a une position précise et une couleur précise.
Les positions sont repérées à l'aide de deux coordonnées x et y dont l'origine se situe en haut à gauche de l'image.
Avant de travailler sur les couleurs des pixels de l'image, il faut générer un tableau contenant l'ensemble des couleurs.
Ce tableau contient une case par pixel. Il a autant de lignes que l'image est haute et autant de colonnes qu'elle est large.
Pour ce faire on utilise la fonction load()
de PIL. Elle renvoie le tableau de valeurs que l'on stocke dans une variable.
tableau = img.load()
# On "affiche" l'objet
print(tableau)
#On affiche les couleurs des 10 premiers pixels de la cinquième ligne (indice 4) de l'image :
# Avec logo.png, ils sont tous noirs (0,0,0) et transparents (le 4ème 0)
for i in range(10) :
print(tableau[4,i])
Les couleurs d'un pixel de coordonnées (x,y) sont accessibles à l'aide de tableau[x,y]
.
# Les dimensions de l'image
largeur, hauteur = img.size
# Les couleurs du pixels du centre de l'image (le // est la division entière)
tableau[largeur//2, hauteur//2]
Comme on peut le voir on obtient un quadruplet en résultat :
Ces différentes valeurs varient entre $0$ et $255$. Il y en a donc $2^8$ ce qui indique que chaque canal ets codé sur un octet.
Le canal alpha ne se trouve pas sur toutes les images. Il n'apparaît jamais sur les images jpg.
Il est ainsi possible de récupérer les valeurs de chaque canal d'un pixel dans des variables et de faire des calculs dessus :
rouge, vert, bleu, alpha = tableau[100,100]
print("Le rouge vaut :",rouge,". Le vert :", vert, sep="") # le sep='' ôte les espaces entre les chaînes
rouge = rouge // 2 # on divise le rouge par 2, le double // permet d'arrondir à l'entier par troncature
vert = min (255, vert * 2) # on double le vert et l'on ne garde que la valeur minimal entre le résultat et 255
print("Le rouge vaut :",rouge,". Le vert :", vert, sep="")
On peut modifier les couleurs d'un pixel de coordonnées en modifiant directement la valeur de la case (i,j) du tableau.
La nouvalle valeur doit être un triplet (rouge, vert, bleu) ou un quadruplet (rouge, vert, bleu, transparence) selon le type d'image.
tableau[0,0] = (255,0,0,255)
img
Notez bien l'unique pixel rouge opaque en haut à gauche !
On peut dès lors modifier l'image dans son ensemble :
largeur, hauteur = img.size # on met à jour ces valeurs car on a redimensionné l'image
for i in range(largeur) :
tableau[i,50] = (255, 0, 0, 255)
img
On a parcouru la ligne 50 en entier et passé tous les pixels en vert opaque (255, 0, 0, 255)
Un dernier exemple : on joue avec les couleurs !
for i in range(largeur) :
for j in range(hauteur) :
rouge, vert, bleu, alpha = img.getpixel((i,j))
rouge = min(255, rouge * 2)
vert = min(255, vert * 3)
bleu = min(255, bleu * 4)
tableau[i,j] = (rouge, vert, bleu, alpha)
img
Remarque :
Deux autres fonctions de PIL permettent d'accéder et de modifier les couleurs des pixels sans passer par le tableau :
getpixel((i,j))
: renvoie la couleur du pixel de coordonnées (i,j). Attention à la double parenthèseputpixel((i,j), (r,g,b,a)
: fixe la couleur du pixel (i,j) à (r,g,b,a) (utiliser (r,g,b) s'il n'y pas de transparence)Plus immédiates, ces fonctions sont toutefois plus lentes à utiliser... On leur préfèrera donc les méthodes décrites ci-dessus.
# Saisir le code ici
print()
) la valeur du canal rouge du pixel du centre de l'image# Saisir le code ici
# Saisir le code ici