Pillow : retouche tes images en lot avec Python, sans ouvrir Photoshop

Pillow : retouche tes images en lot avec Python, sans ouvrir Photoshop

De quoi avez-vous besoin

Version de Python

3.x

Packages

  • {"nom": "Pillow", "version": "12.x"}

Difficulté

Débutant

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.

bash
pip install Pillow

On 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.

python
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.

python
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.

python
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.

python
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.

python
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.

python
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.