Tu as un dossier rempli d'images : trop lourdes pour ton site, mal cadrées, jamais signées. Les retoucher une à une dans un logiciel, c'est une après-midi entière de perdue. Pillow, la bibliothèque d'imagerie de Python, fait exactement le même travail en quelques lignes — et surtout, elle le fait en boucle sur des centaines de fichiers pendant que tu bois ton café.
Pillow, le successeur moderne de PIL, est la référence pour manipuler des images en Python : ouvrir, redimensionner, rogner, pivoter, convertir, compresser, appliquer des filtres et poser du texte. Pas d'interface graphique, pas de Photoshop, rien d'autre qu'un pip install. Il lit et écrit plus de trente formats, du JPEG au WebP en passant par le PNG, le GIF ou le TIFF.
Dans ce tutoriel, tu vas automatiser tout ça par lot, avec du code que tu peux copier-coller tel quel. Chaque étape est indépendante : pioche celle dont tu as besoin, ou enchaîne-les pour construire un vrai pipeline de retouche.
1. Installer Pillow et ouvrir sa première image
L'installation tient en une commande. Pour le reste, tout passe par la classe Image et ses méthodes. Bonne nouvelle : open() ne charge pas l'image en mémoire tout de suite, il se contente de lire les métadonnées. Ouvrir un fichier est donc quasi instantané, même sur une photo de 20 mégaoctets.
pip install PillowOn ouvre un fichier et on l'inspecte. Le tuple renvoyé par size suit l'ordre (largeur, hauteur), un piège classique quand on débute. format indique le type du fichier, et mode décrit la façon dont les pixels sont codés : RGB pour la couleur, L pour le noir et blanc, RGBA quand il y a de la transparence.
from PIL import Image
import os
img = Image.open("photo.jpg")
print(img.format) # JPEG
print(img.mode) # RGB
print(img.size) # (largeur, hauteur), ex: (4000, 3000)
print(os.path.getsize("photo.jpg"), "octets")2. Redimensionner et créer des miniatures
Deux outils pour réduire une image, et ils ne servent pas à la même chose. resize() force des dimensions précises, quitte à déformer l'image ; thumbnail() respecte les proportions et modifie l'image en place, sans jamais dépasser la taille demandée. Pour redimensionner sans écraser le ratio, calcule-le toi-même comme ci-dessous.
largeur, hauteur = img.size
ratio = 400 / largeur
img.resize((400, int(hauteur * ratio))).save("photo_400.jpg")
# thumbnail conserve les proportions et ne dépasse jamais (200, 200)
img.thumbnail((200, 200))
img.save("photo_mini.jpg")Au passage, tu peux préciser un algorithme de rééchantillonnage avec le paramètre resample=Image.Resampling.LANCZOS. C'est le meilleur choix pour réduire une photo sans perdre en netteté, là où la valeur par défaut suffit pour des images simples.
3. Rogner et pivoter
crop() découpe un rectangle défini par (gauche, haut, droite, bas), en pixels mesurés depuis le coin supérieur gauche — pas depuis le centre. rotate() fait pivoter dans le sens horaire ; le paramètre expand=True agrandit le canevas pour ne rien couper pendant la rotation.
img = Image.open("photo.jpg")
img.crop((100, 50, 700, 550)).save("photo_crop.jpg")
img.rotate(90, expand=True).save("photo_rot.jpg")Pour un simple effet miroir, transpose() est plus direct : Image.Transpose.FLIP_LEFT_RIGHT inverse l'image horizontalement en une seule opération, sans calcul d'angle.
4. Compresser et convertir un dossier entier
C'est ici que Pillow paie vraiment. Pour alléger un site ou une galerie, rien ne bat le format WebP : à qualité visuelle équivalente, il pèse souvent cinq à dix fois moins qu'un JPEG. On parcourt un dossier et on convertit tout d'un coup, sans même ouvrir les fichiers.
import glob
for fichier in glob.glob("images/*.jpg"):
Image.open(fichier).convert("RGB").save(
fichier.replace(".jpg", ".webp"),
"WEBP", quality=70
)Le convert("RGB") est essentiel avant d'enregistrer en JPEG ou WebP : il supprime l'éventuel canal alpha (la transparence) que ces formats ne gèrent pas. Sans lui, tu récoltes une erreur du type cannot write mode RGBA as JPEG. La qualité, entre 1 et 100, est ton curseur entre poids du fichier et netteté : 70 est un bon compromis pour le web.
5. Ajouter un filigrane
Pour signer tes images, on dessine du texte sur un calque transparent, puis on fusionne les deux avec alpha_composite(). Le cachet se place automatiquement en bas à droite, position calculée à partir des dimensions réelles du texte — pas à l'arrache.
from PIL import ImageDraw, ImageFont
base = Image.open("photo.jpg").convert("RGBA")
calque = Image.new("RGBA", base.size, (255, 255, 255, 0))
dessin = ImageDraw.Draw(calque)
police = ImageFont.load_default(size=48)
texte = "iancr.com"
bbox = dessin.textbbox((0, 0), texte, font=police)
w, h = bbox[2] - bbox[0], bbox[3] - bbox[1]
dessin.text((base.width - w - 20, base.height - h - 20),
texte, font=police, fill=(255, 255, 255, 160))
Image.alpha_composite(base, calque).convert("RGB").save("photo_signee.jpg")load_default() donne une police basique, mais tu peux charger n'importe quel fichier .ttf avec ImageFont.truetype("police.ttf", 48) pour coller à ta charte graphique. Le quatrième paramètre de fill() est l'opacité, de 0 à 255 : 160 donne un filigrane discret mais lisible.
6. Filtres, contraste et niveaux de gris
Pillow embarque des filtres prêts à l'emploi (flou, netteté, contours) et un module ImageEnhance pour ajuster luminosité, contraste, couleur et netteté. La valeur passée à enhance() est un multiplicateur : 1.0 ne change rien, 1.5 accentue, 0.5 atténue.
from PIL import ImageFilter, ImageEnhance
img = Image.open("photo.jpg")
img.filter(ImageFilter.GaussianBlur(3)).save("photo_floue.jpg")
img.convert("L").save("photo_nb.jpg") # niveaux de gris
ImageEnhance.Contrast(img).enhance(1.5).save("photo_contraste.jpg")ImageEnhance ne se limite pas au contraste : Brightness, Color et Sharpness suivent exactement la même logique. convert("L") transforme une image en niveaux de gris, pratique pour préparer des documents à l'impression ou alléger un traitement.
À toi de jouer
En combinant ces six briques, tu peux écrire un script qui avale un dossier de photos brutes et recrache, en quelques secondes, des versions redimensionnées, converties en WebP et signées, prêtes à publier. C'est précisément le genre de tâche qui t'aurait pris une heure à la main, fichier par fichier.
Pillow ne remplace pas un logiciel de retouche pour du travail fin, et il ne fait pas d'IA. Mais pour 90 % des manipulations du quotidien, c'est l'outil le plus rapide qui existe. La documentation officielle liste des dizaines d'autres filtres, formats et méthodes ; commence par les six ci-dessus, enchaîne-les dans une boucle, et ton prochain dossier d'images se traitera tout seul.






