Des articles approfondis sur les technologies qui façonnent l'avenir.

Comment fonctionne vraiment la compression JPEG

Visite visuelle de la compression JPEG : transformée DCT, tables de quantification, et pourquoi certaines images se compressent mieux que d'autres.

Une image de fleur qui se désintègre en blocs de pixels, puis en motifs d'ondes tourbillonnants

JPEG est le cafard des formats de fichiers. Standardisé en 1992, il est antérieur au navigateur web et a survécu à toutes les tentatives de le remplacer. WebP, AVIF, HEIC : tous compressent mieux, et pourtant JPEG reste le format d'image le plus utilisé sur Internet. Une part de cela tient à l'inertie. Mais une autre part tient au fait que le pipeline de compression de JPEG est vraiment brillant, un cours magistral de traitement du signal appliqué qui mérite d'être compris, même si vous n'écrirez jamais d'encodeur.

La plupart des développeurs traitent JPEG comme une boîte noire : on y met une image, on en sort un fichier plus petit, et on monte le curseur de qualité jusqu'à ce que le résultat paraisse acceptable. Mais comprendre ce qui se passe à l'intérieur de la boîte change la façon dont on pense aux images, à la compression et aux compromis entre taille de fichier et qualité visuelle.

Le pipeline en un coup d'œil

La compression JPEG est un pipeline de cinq étapes, chacune astucieuse à sa manière. La magie tient à leur enchaînement : chaque étape prépare la suivante pour qu'elle soit plus efficace.

  1. Conversion d'espace colorimétrique : RGB vers YCbCr (on sépare la luminosité de la couleur)
  2. Sous-échantillonnage chromatique : on réduit la résolution des canaux de couleur
  3. Transformée en cosinus discrète (DCT) : on convertit les données spatiales en données fréquentielles
  4. Quantification : on élimine les détails à haute fréquence (c'est l'étape avec perte)
  5. Codage entropique : compression sans perte des données quantifiées

Les étapes 1 et 2 exploitent le fonctionnement de la vision humaine. Les étapes 3 et 4 exploitent les propriétés des images naturelles. L'étape 5 est de la compression de données classique. Chaque étape est simple prise isolément. L'intérêt réside dans leur enchaînement.

Étape 1 : conversion de l'espace colorimétrique

Votre appareil photo capture les images en RGB, avec des canaux rouge, vert et bleu, chacun sur 8 bits par pixel. La première opération de JPEG consiste à convertir ces données en YCbCr : un canal de luminance (la luminosité) et deux canaux de chrominance (la couleur). Ce n'est pas encore de la compression, aucune donnée n'est perdue. C'est une transformation de coordonnées, comparable à une rotation des axes.

Pourquoi s'en embêter ? Parce que l'œil humain est bien plus sensible à la luminosité qu'à la couleur. Vous percevez des détails extrêmement fins dans une photo en noir et blanc, alors que votre perception de la résolution des couleurs est beaucoup plus grossière. En séparant la luminosité de la couleur, JPEG peut traiter les deux différemment : il préserve le détail de luminosité tout en réduisant fortement le détail chromatique.

RGB to YCbCr conversion (simplified):
Y  =  0.299R + 0.587G + 0.114B    (luminance — brightness)
Cb = -0.169R - 0.331G + 0.500B    (blue chrominance)
Cr =  0.500R - 0.419G - 0.081B    (red chrominance)
Note: green dominates the luminance calculation because
human eyes have far more green-sensitive cone cells.
This isn't arbitrary — it matches the physiology.

Étape 2 : sous-échantillonnage chromatique

C'est ici que se produit la première vraie réduction de données. Comme les humains ne perçoivent pas la couleur à pleine résolution spatiale, JPEG réduit la résolution des canaux Cb et Cr, généralement de moitié dans les deux dimensions. C'est ce qu'on appelle le sous-échantillonnage 4:2:0. Pour quatre pixels de luminance, il n'y a qu'un seul échantillon de chrominance.

Résultat : vous venez de diviser par deux les données brutes (passant de 3 canaux en pleine résolution à 1 canal pleine résolution et 2 canaux au quart de la résolution), et l'image reste pratiquement identique à l'original. Essayez par vous-même : prenez une photo quelconque, réduisez la résolution des canaux couleur par 4, et vous aurez du mal à voir la différence. Votre cerveau reconstitue le détail chromatique à partir de l'information de luminance.

Cela ne fonctionne pas aussi bien pour toutes les images. Les photographies se compressent très bien, car les scènes naturelles présentent des dégradés de couleur doux. En revanche, les images avec des frontières de couleur nettes, comme du texte sur fond coloré, un cercle rouge sur fond blanc ou du pixel art, montrent des franges de couleur visibles après sous-échantillonnage. C'est pour cette raison que JPEG est mauvais pour le texte : les bords colorés nets se diffusent.

Étape 3 : la transformée en cosinus discrète

C'est là que JPEG devient intéressant. L'image est découpée en blocs de 8×8 pixels, et chaque bloc est transformé du domaine spatial (les valeurs de luminosité des pixels) vers le domaine fréquentiel (la quantité présente pour chaque fréquence spatiale).

Imaginez les choses ainsi : un bloc de 8×8 pixels peut être représenté comme une somme pondérée de 64 motifs de base. Le premier motif est un bloc uniforme (la valeur moyenne). Les suivants ajoutent des dégradés horizontaux et verticaux. Les motifs numérotés plus haut ajoutent des détails de plus en plus fins, des oscillations rapides de luminosité.

An 8x8 DCT block conceptually:
DC ──► Low frequency ──────────────► High frequency
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│ AVG │  →  │  →  │  →  │  →  │  →  │  →  │  →  │ Low freq
│     │     │     │     │     │     │     │     │   ↓
│  ↓  │  ↘  │     │     │     │     │     │     │
│     │     │  ↘  │     │     │     │     │     │
│     │     │     │  ↘  │     │     │     │     │
│     │     │     │     │  ↘  │     │     │     │
│     │     │     │     │     │  ↘  │     │     │
│     │     │     │     │     │     │  ↘  │     │
│     │     │     │     │     │     │     │ FINE │ High freq
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
Top-left = low frequency (smooth gradients)
Bottom-right = high frequency (sharp edges, fine detail)
Natural images: most energy concentrated in top-left
Text/line art: significant energy in bottom-right

La DCT elle-même est sans perte : vous pouvez reconstruire parfaitement le bloc 8×8 d'origine à partir de ses 64 coefficients. Mais voici la propriété décisive : pour les images naturelles (photos, dégradés, textures organiques), l'essentiel de l'énergie se concentre dans les coefficients basses fréquences. Les coefficients hautes fréquences, qui représentent les détails fins, tendent à être petits. C'est ce qui rend l'étape suivante efficace.

Pourquoi 8×8 ? C'est un compromis. Des blocs plus grands (16×16, 32×32) concentreraient mieux l'énergie, mais coûteraient plus cher en calcul et provoqueraient des artefacts de « blocs » visibles à faible qualité. Des blocs plus petits (4×4) réduiraient ces artefacts, mais ne concentreraient pas aussi bien l'énergie. Le 8×8 s'est révélé être le bon équilibre, qui tient depuis plus de 30 ans.

Étape 4 : la quantification, là où les données meurent

C'est l'étape avec perte. Chaque coefficient DCT est divisé par une valeur correspondante issue d'une table de quantification, puis arrondi à l'entier le plus proche. Les grands diviseurs (pour les coefficients hautes fréquences) ramènent les petites valeurs à zéro. Ces zéros sont perdus à jamais : c'est ici que l'information est définitivement supprimée.

Example quantization (quality ~50):
DCT coefficient: 42.7    Quantization divisor: 16    Result: round(42.7/16) = 3
DCT coefficient: 8.3     Quantization divisor: 40    Result: round(8.3/40)  = 0
DCT coefficient: -2.1    Quantization divisor: 99    Result: round(-2.1/99) = 0
The quality slider in your image editor controls the quantization table.
Quality 100: divisors close to 1 (almost no rounding, huge file)
Quality 75:  moderate divisors (good balance, typical web use)
Quality 50:  large divisors (noticeable artifacts, small file)
Quality 10:  very large divisors (blocky mess, tiny file)

La table de quantification est le facteur le plus important de la qualité JPEG. La norme JPEG définit une table par défaut, mais les encodeurs peuvent utiliser celle qu'ils veulent. Les encodeurs modernes comme MozJPEG utilisent des tables optimisées qui tirent davantage de qualité de fichiers plus petits, en ajustant les diviseurs selon la sensibilité perceptive humaine : ils sont plus agressifs sur les fréquences auxquelles nous sommes moins sensibles.

Après quantification, un bloc 8×8 typique, à qualité moyenne, compte environ 6 à 10 coefficients non nuls sur 64. Les autres sont à zéro. Cette forte réduction du nombre de valeurs non nulles est ce qui rend l'étape finale de compression efficace.

Étape 5 : codage entropique

La dernière étape est une compression sans perte des coefficients quantifiés. JPEG combine le codage par plages (RLE, pour run-length encoding) et le codage de Huffman. Les coefficients sont lus en zigzag dans le bloc 8×8, en partant du coefficient DC (en haut à gauche) puis en parcourant les fréquences croissantes. Cela regroupe tous les zéros de fin, que le RLE gère efficacement : au lieu de stocker « 0, 0, 0, 0, 0, 0, ..., 0 », il stocke « quarante-sept zéros ».

Le codage de Huffman attribue ensuite des séquences de bits plus courtes aux valeurs les plus fréquentes et plus longues aux valeurs rares. Comme la plupart des coefficients non nuls sont de petits entiers (1, -1, 2, -2), ils reçoivent des codes très courts. Le résultat : le bloc 8×8 quantifié, qui commençait avec 64 valeurs, tient généralement en 20 à 40 octets selon le contenu de l'image et le réglage de qualité.

Pourquoi certaines images se compressent mieux que d'autres

Comprendre le pipeline explique des comportements de compression qui paraîtraient autrement mystérieux.

  • Les photographies se compressent bien car elles présentent des dégradés de couleur doux (le sous-échantillonnage chromatique fonctionne à merveille) et l'essentiel de l'énergie se trouve dans les coefficients DCT basses fréquences (la quantification annule beaucoup de coefficients sans impact visible).
  • Le texte et les dessins au trait se compressent mal car les bords nets produisent des coefficients DCT hautes fréquences importants, impossibles à annuler sans artefacts visibles. Les frontières des blocs 8×8 deviennent visibles sous forme de halos autour des contours du texte.
  • Le bruit détruit la compression car le bruit du capteur est une donnée aléatoire à haute fréquence. Chaque pixel bruité ajoute des coefficients hautes fréquences non nuls, qui résistent à la quantification. Une photo bruitée à qualité 80 peut peser 3 à 5 fois plus lourd qu'une photo nette de la même scène, à la même qualité.
  • Les dégradés ne coûtent presque rien car un dégradé lisse sur un bloc 8×8 est représenté par seulement 2 ou 3 coefficients DCT. Les autres sont à zéro, même sans quantification.
  • Ré-enregistrer dégrade la qualité car chaque sauvegarde réapplique la quantification. Les erreurs d'arrondi s'accumulent. Enregistrer un JPEG 10 fois à la qualité 75 donne un résultat nettement moins bon qu'un seul enregistrement à qualité 75. C'est pourquoi il faut toujours éditer à partir du fichier source original.

Le curseur de qualité n'est pas linéaire

La plupart des développeurs traitent le curseur de qualité JPEG comme un compromis linéaire : la qualité 50 représenterait la moitié de la qualité 100, pour moitié moins de poids. Ce n'est vrai ni pour l'un ni pour l'autre.

La qualité 100 n'est pas « sans perte » : la quantification s'applique toujours, simplement avec de petits diviseurs. Le fichier est énorme (souvent plus lourd qu'un PNG) et visuellement indiscernable de la qualité 95. Pour les photos, la qualité 95 est indiscernable de la qualité 90. La différence perceptive entre les qualités 85 et 75 est plus grande qu'entre 100 et 85. En dessous de 50, les artefacts deviennent sévères et la baisse de poids ralentit.

Le point idéal pour les images web se situe généralement entre 75 et 85. En dessous de 75, les artefacts sont visibles à taille d'affichage normale. Au-dessus de 85, le poids augmente sensiblement pour un gain perceptif négligeable. La qualité 75 par défaut de MozJPEG est bien choisie : elle se situe au coude de la courbe qualité/taille pour la plupart des photos.

Les encodeurs JPEG modernes sont plus malins qu'on ne le pense

La norme JPEG définit le format de décodage, et non l'encodeur. Cela signifie que les implémentations d'encodeurs peuvent avoir une efficacité de compression radicalement différente tout en produisant des fichiers conformes à la norme. MozJPEG, développé par Mozilla, produit des fichiers de 5 à 15 % plus légers que libjpeg à qualité visuelle égale, grâce à plusieurs techniques.

  • Quantification par treillis (trellis quantization) : au lieu d'arrondir chaque coefficient DCT indépendamment, cette méthode tient compte de l'effet de chaque décision d'arrondi sur l'étape de codage entropique, et fait des choix globalement meilleurs.
  • Tables de Huffman optimisées : les tables de Huffman JPEG par défaut sont génériques. MozJPEG génère des tables sur mesure, adaptées à la distribution réelle des coefficients de chaque image.
  • Encodage progressif : les JPEG progressifs stockent les coefficients en plusieurs passes (d'abord grossière, puis en affinage). Cela compresse souvent mieux que l'encodage séquentiel, car la passe grossière a une distribution de coefficients plus prévisible.
  • Tables de quantification adaptatives : au lieu d'une seule table pour toute l'image, les encodeurs adaptatifs ajustent la quantification par zone, plus agressive dans les zones chargées (où les artefacts se voient moins) et plus prudente dans les zones lisses.

Si vous servez des images sur le web, passer de l'encodeur libjpeg par défaut à MozJPEG est l'un des gains de performance les plus faciles à obtenir. La plupart des CDN d'images et des bibliothèques de traitement le prennent en charge. L'encodage est plus lent (ce qui n'a pas d'importance pour des images statiques prétraitées), et le résultat est plus léger à qualité égale.

JPEG face aux nouveaux formats

WebP, AVIF et HEIC utilisent des techniques de compression plus modernes : blocs de transformée plus grands, filtres de déblocage en boucle, prédiction intra (utiliser les blocs voisins pour prédire le bloc courant). Ils sont 20 à 50 % plus efficaces que JPEG à qualité visuelle égale. AVIF, basé sur le codec vidéo AV1, est particulièrement impressionnant.

Alors pourquoi JPEG est-il toujours partout ? Parce qu'il est universel. Chaque navigateur, chaque visionneuse d'images, chaque système d'exploitation, chaque appareil photo, chaque téléphone et chaque logiciel gérant des images le prend en charge. WebP est presque universel dans les navigateurs, mais manque de support natif dans les OS. La prise en charge d'AVIF reste inégale. HEIC relève surtout de l'écosystème d'Apple. Pour un format qui doit fonctionner partout, JPEG reste le seul choix sûr.

Mon conseil pratique : utilisez AVIF ou WebP avec un repli en JPEG si votre infrastructure de diffusion le permet (la plupart des CDN le font via la négociation de contenu). Si vous ne pouvez en choisir qu'un seul, un JPEG encodé avec MozJPEG à qualité 80 est difficile à battre pour les photographies. Pour les captures d'écran, les schémas et les images riches en texte, le PNG reste le meilleur choix, ou explorez d'autres approches plus créatives de la représentation des images.

Le bloc 8×8 qui a conquis le monde

Le pipeline de compression de JPEG est un exemple d'école d'ingénierie qui travaille avec la perception humaine plutôt que contre elle. Chaque étape exploite une propriété précise (l'insensibilité à la couleur, la distribution des fréquences des images naturelles, le masquage perceptif du bruit de quantification), et l'ensemble forme un système qui réduit les fichiers de 10 à 20 fois avec un impact visible minime. Trente-quatre ans plus tard, les mêmes blocs DCT 8×8 qui tournaient sur le matériel de 1992 transportent encore la plupart des images d'Internet. C'est la marque d'une conception qui a bien posé les fondamentaux.