On suppose qu'un objet Image a été créé par l'une des méthodes évoquées précédemment. On peut alors appliquer un certain nombre de méthodes à cet objet :
Ecrit l'image dans un fichier. L'argument f est soit le nom du fichier, soit un objet fichier. Le deuxième argument précise quelle sorte de fichier image écrire : un des codes de format de fichier listés plus loin (tel "JPEG", "TIFF").
>>> import Image as im
>>> image.getpixel((5,8),223) >>> image.save('coucou.png') >>> ff=open('coucou2.png','w') >>> image.save(ff)
Renvoie une nouvelle image dans un mode différent.
>>> image = im.open('chaos.png') >>> image.mode 'P' >>> image = image.convert('RGB') >>> image.mode 'RGB'
Renvoie une copie de l'image.
>>> image = im.open('chaos.png') >>> image.getpixel((1,1)) 0 >>> image2 = image.copy() >>> image.putpixel((1,1),1) >>> image.getpixel((1,1)) 1 >>> image2.getpixel((1,1)) 0
Renvoie une nouvelle image constituée par la bbox (spécifiée en argument) correspondante de l'image d'origine. Noter que
>>> im.crop((0,0,3,3))
a pour taille 3x3, puisque la ligne et la colonne contenant le pixel (3,3) ne sont pas pris.
Renvoie une copie de l'image, filtrée avec le filtre d'amélioration du nom de name (c.f. le module ImageFilter).
>>> import Image as im >>> import ImageFilter >>> image = im.open('chaos.png') >>> image = image.filter(ImageFilter.BLUR) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.5/site-packages/PIL/Image.py", line 787, in filter return self._new(filter.filter(self.im)) File "/usr/lib/python2.5/site-packages/PIL/ImageFilter.py", line 54, in filter raise ValueError("cannot filter palette images") ValueError: cannot filter palette images >>> image.mode 'P' >>> image = image.convert('L') >>> image = image.filter(ImageFilter.BLUR)
Renvoie une suite de chaînes de caractères, une par bande, représentant le mode de l'image.
Par exemple, si im a pour mode "RBG" :
>>> im.getbands() ('R', 'G', 'B')
Renvoie la plus petite bbox qui enferme la partie non nulle de l'image.
>>> import Image as im >>> from numpy import * >>> image = im.new('L',(5,5)) >>> image.putpixel((1,1),5) >>> image.putpixel((2,3),4) >>> print transpose(array(image.getdata()).reshape(5,5)) [[0 0 0 0 0] [0 5 0 0 0] [0 0 0 4 0] [0 0 0 0 0] [0 0 0 0 0]] >>> image.getbbox() # Le coin inférieur droit n'est pas pris (1, 1, 3, 4)
Renvoie le contenu d'une image dans une suite contenant les valeurs des pixels. La suite est "étalée" : les valeurs de la seconde ligne suivent immédiatement celles de la première, etc.
La suite renvoyées par cette méthode est un type de données interne à PIL, qui ne supporte que certaines opérations. Pour le convertir dans une suite "ordinaire", utiliser :
>>> list(im.getdata())
Dans le cas des images simple-bande, renvoie un couple (min,max), où min est la plus petite valeur, et max la plus grande valeur, des pixels de l'image. Dans le cas des images multi-bandes, renvoie le tuple des couples (min,max) pour chaque bande.
>>> import Image as im >>> image = im.open('image1.png') >>> print image.mode, image.getextrema() P (0, 237) >>> image = im.open('image2.png') >>> print image.mode, image.getextrema() RGB ((4, 252), (2, 254), (4, 252))
Retourne la (ou les) valeur(s) du pixel de coordonnées xy.
>>> import Image as im >>> image = im.open('image1.png') >>> print image.mode, image.getpixel((5,8)) RGB (252, 254, 252) >>> image = im.open('image2.png') >>> print image.mode, image.getpixel((5,8)) P 136
Pour les images simples-bandes, renvoie une liste de valeurs [c0, c1, ...], où ci est le nombre de pixels ayant la valeur i. Pour les multi-bandes, les différentes listes de valeurs (pour chaque bande) sont concaténées.
>>> image = im.open('image.jpeg') >>> print image.mode, len(image.histogram()) L 256 >>> image.histogram()[:10] [3665, 1681, 921, 750, 626, 641, 555, 479, 451, 442] >>> image = im.open('image2.jpeg') >>> print image.mode RGB >>> len(image.histogram())==3*256 True
On a bien une liste trois fois plus longue que le nombre de pixels (il y a trois bandes). Représentons les différents histogrammes :
>>> import pylab >>> pylab.plot(range(256),image.histogram()[:256], color = 'red') [<matplotlib.lines.Line2D instance at 0x8c7994c>] >>> pylab.plot(range(256),image.histogram()[256:2*256], color = 'green') [<matplotlib.lines.Line2D instance at 0x8c79a4c>] >>> pylab.plot(range(256),image.histogram()[2*256:3*256], color = 'blue') [<matplotlib.lines.Line2D instance at 0x8c79b4c>] >>> pylab.show()
Pour avoir un histogramme d'un ensemble particulier de pixels de l'image, passer en argument une image (masque) de la même taille que celle d'origine, et de mode "1" ou "L". L'histogramme résultant inclura seulement les pixels de l'image d'origine qui correspondent aux pixels non nuls du masque.
Illustrons cela :
>>> image = im.open('image.jpeg') >>> print image.mode, image.size L (300,300) 256
On crée un masque de même taille, remplis de 0, et avec 100 uns (placés aléatoirement)
>>> masque = im.new('1',(300,300)) >>> from random import randint >>> liste = [0]*300**2 >>> for k in range(100): ... liste[randint(0,300**2)] = 1 ... >>> masque.putdata(liste)
On vérifie alors qu'il n'y a bien que 100 pixels dans l'histogramme :
>>> sum(image.histogram(masque)) 100
Les pixels sont remplacés par ceux de i2.
:* Si le mode du mask est "1", les pixels de l'image originale sont laissés tel quel quand un 0 est rencontré dans le masque, et sont remplacée quand un 1 est rencontré.
:* Si le mode du mask est "L", les pixels de l'image originale sont laissés tel quel quand un 0 est rencontré dans le masque, et sont remplacée quand un 255 est rencontré. Pour les valeurs intermédiaires, il y aura interpolation entre les valeurs des pixels de l'image d'origine et de l'image de remplacement.
:* Si le mode du mask est "RGBA", sa bande "A" est utilisée de la même manière que pour un masque de mode "L".
Fixe la même couleur à de multiples pixels. Si l'argument box est omis, l'image toute entière est transformée en cette couleur. Si un masque est fournis, alors les pixels non nuls de ce masque sont ceux dont la couleur changera.
Pour appliquer une fonction à chaque pixel, appeler cette méthode, qui renvoie l'image correspondant à l'application de cette fonction à chaque pixel de l'image originale. La fonction doit s'appliquer à un pixel (valeur de 0 à 255), et retourner un pixel (même genre de valeurs).
Exemple d'utilisation : réaliser facilement son propre filtre négation.
>>> import Image as im >>> dd=im.open('cover.jpeg') >>> dd.getpixel((1,1)) (76, 65, 61) >>> def f(x): ... return 255-x ... >>> dd=dd.point(f) >>> dd.getpixel((1,1)) (179, 190, 194) >>> dd.show()
Pour transformer les pixels suivant une table, passer cette dernière en argument à la méthode point. La table doit être une suite de 256<sup>n</sup> valeurs, où n est le nombre de bandes de l'image. Chaque pixel de la bande b de l'image sera remplacé par la valeur de table[p+256*b], où p est l'ancienne valeur du pixel dans la bande considérée.
Ainsi, si l'on a une image en niveaux de gris, et que l'on passe une table (de 256 valeurs, donc) telle que table[2] = 7 et table[236] = 0, alors tous les pixels de valeur 2 seront transformés en 7, et tous ceux de valeur 236 seront transformés en 0 (d'un gris clair, en noir pur).
Prenons un exemple : si l'on souhaite tranformer notre image, de sorte que toutes les valeurs pairs des pixels soient divisées par 2, on procèdera ainsi...
>>> import Image as im >>> dd=im.open('image.jpeg') >>> dd.getbands() ('L',)
Nous avons donc une image en niveaux de gris. Regardons les valeurs de deux pixels témoins :
>>> dd.getpixel((1,1)), dd.getpixel((1,2)) (56, 37)
Pour table, on va donc prendre la liste des entiers de 0 à 255...sauf que chaque terme pair sera divisé par 2. Cela peut se faire de la manière suivante :
>>> table = [(k/2 if k%2==0 else k) for k in range(256)]
Il nous reste à appliquer notre table à notre image...
>>> dd=dd.point(table) >>> dd.getpixel((1,1)), dd.getpixel((1,2)) (28, 37)
Dans le cas RGB, il faut une table trois fois plus longue, vu qu'il y a trois bandes de 256 valeurs. La version adaptée de ce qui précède sera donc :
>>> import Image as im >>> dd=im.open('image2.jpeg') >>> dd.getpixel((1,1)) (76, 65, 122) >>> table = [((k%256)/2 if k%2==0 else k%256) for k in range(3*256)] >>> dd=dd.point(table) >>> dd.getpixel((1,1)) (38, 65, 61)
Les valeurs pairs ont bien été divisées par 2.
Pour ajouter une bande alpha (transparence) à une image de mode "RGBA", utilisez cette méthode, avec une image de même taille et de mode "L" ou "A" en argument. Les pixels de l'image band remplaceront la bande alpha.
>>> dd=im.open('cover.jpeg') >>> dd = dd.convert('RGBA') >>> dd.getbands() ('R', 'G', 'B', 'A') >>> dd.getpixel((1,1)) (76, 65, 61, 255) >>> ee=im.open('cover.jpeg') >>> ee = ee.convert('L') >>> ee.getpixel((1,1)) 67 >>> dd.putalpha(ee) >>> dd.getpixel((1,1)) (76, 65, 61, 67) >>> dd.show()
Copie les valeurs des pixels à partir d'une suite dans une image. Le point de départ est le coin supérieur gauche de l'image. Les arguments scale et offset sont utilisés pour ajuster ces valeurs :
pixel = value * scale + offset
Si l'échelle (scale) est omise, sa valeur par défaut est 1.0. Si offset n'est pas spécifié, il sera égal à 0.0.
data doit être une suite. Voici comment convertir une matrice numpy pour la méthode putdata :
>>> import Image as im >>> dd=im.new('L',(3,3)) >>> from numpy import * >>> dd.putdata(array([ [1,50,200],[100,200,0],[50,150,250] ])) >>> dd.show()
Là, rien ne se passe. Par contre...
>>> jj=array([ [1,50,200],[100,200,0],[50,150,250] ]) >>> dd.putdata(jj.flatten()) >>> dd.show()
Remplace le pixel xy de l'image. Pour les images multi-bandes, la valeur est un tuple
>>> im.putpixel((0,0), (0,255,0))
Remplacer un certain nombre de pixels par cette méthode peut s'avérer long : voir le module ImageDraw pour des techniques plus rapides.
Renvoie une nouvelle image ayant la taille spécifiée, en procédant linéairement. Un filtre (resample) peut être fournis pour préciser comment l'interpolation doit être faite (par défaut : NEAREST).
>>> import Image >>> dd = Image.open('cover.jpeg') >>> dd.size (300, 300) >>> dd = dd.resize((240,279)) >>> dd.size (240, 279) >>> dd = dd.resize((40,80), resample = Image.BICUBIC) >>> dd.size (40, 80)
Les quatre filtres applicables, à savoir NEAREST, BILINEAR, BICUBIC, ANTIALIAS, sont définis ici.
Renvoie une image qui a tournée d'un angle theta, en degré, par rapport au centre de l'image considérée. Le sens de la rotation est trigonométrique (sens contraire des aiguilles d'une montre). Du fait de la rotation, des pixels de couleur noir apparaissent aux coins de l'image.
>>> import Image >>> dd = Image.open('cover.jpeg') >>> dd=dd.rotate(45) >>> dd.show()
On constate que l'image sort maintenant de la fenêtre
>>> dd=dd.rotate(-45) >>> dd.show()
On a donc bien perdu les coins de l'image. Pour changer de méthode d'approximation :
>>> dd = dd.rotate(80, resample = Image.BICUBIC)
Enfin, pour éviter de perdre les coins de l'image...
>>> dd=dd.rotate(45, expand = 1) >>> dd.size (426, 425)
Seulement, le noir introduit dans l'image, fait dorénavant partie de l'image...
>>> dd=dd.rotate(-45, expand = 1) >>> dd.size (602, 603)
Sur station Unix, le programme xv est lancé pour visualiser l'image. Sur Windows, l'image est sauvegardée en BMP, et peut être vue avec Paint.
Attention, sur certaines distributions, la commande xv n'existe plus. il suffit de créer un lien de cette commande vers la commande display par exemple
$~/bin ln -s /usr/bin/display xv
Renvoie un tuple contenant chaque bande de l'image originale, vue comme une image de mode "L". Par exemple, appliquer cette méthode à une image "RGB" produit un triplet d'images, la première pour la bande rouge, la seconde pour la verte et la dernière pour la bleue.
Remplace l'image originale par une nouvelle image ayant la taille size. Le filtre optionnel fonctionne comme pour la méthode resize().
L'image d'arrivée aura sa plus grande taille inférieure ou égale à size, avec le même rapport longueur/largeur que l'original. Par exemple, si l'image im avait une taille (400,150), le résultat de im.thumbnail((40,40)) aura pour taille (40,15).
Renvoie une transformation de l'image : le point originellement en (x0,y0) se retrouvera en (0,0), et le point (x1,y1) en (xs, ys).
Transformation affine. Les valeurs de a à f correspondent aux deux premières lignes de la matrice de transformation affine : chaque pixel (x,y) de l'image résultante provient de la position (ax+by+c,dx+ey+f) de l'image originale (avec arrondis au pixel le plus proche).
Renvoie une copie, culbutée ou retournée, de l'image originale. L'argument methode peut être :
>>> import Image as im
>>> image = image.transpose(im.ROTATE_90) >>> image.show()