Skip to content
Retour au blog
Tutoriels

Image compressée plus lourde ? Les 3 causes réelles

Un compresseur qui alourdit vos fichiers n'est pas cassé : le canvas du navigateur réencode en RGBA 32 bits. Mesuré sur 83 PNG réels, les 83 ont grossi. Outil gratuit.

14 min de lecture

Image compressée plus lourde ? Les 3 causes réelles

Votre compresseur va sans doute très bien. Quand la compression d’image ne fonctionne pas (le fichier ressort à la même taille, ou nettement plus lourd que celui que vous avez fourni), la cause est presque toujours l’une de trois choses. Aucune des trois n’est un outil cassé.

La plus fréquente d’abord. Tout outil qui compresse via l’élément canvas du navigateur jette le type de couleur de votre PNG et réencode chaque pixel en RGBA 32 bits. Nous avons fait passer les 83 PNG de cartes Open Graph de ce site dans canvas.toBlob('image/png') sous Chrome 151.0.0.0. Les 83 sont revenus plus lourds. La croissance médiane est de +76,6 %, la plus faible de +35,6 %, la plus forte de +237,2 %.

Deuxième cause : votre JPEG est déjà compressé. Faites-lui subir cinq passes en qualité 0.8 et la taille cesse de bouger après la deuxième, alors que chaque passe continue de dégrader l’image.

Troisième : votre PNG a déjà été quantifié. Il ne reste plus la moindre redondance de couleurs qu’une seconde passe pourrait retirer.

Aucun de ces cas ne se règle en descendant le curseur de qualité. Le correctif, c’est un autre format ou un autre encodeur. Ces mêmes 83 PNG convertis en WebP en qualité 0.8 ont tous diminué, médiane −94,2 %.

Comment ces chiffres ont été produits. Chrome 151.0.0.0 piloté par Playwright, macOS 26.5.2, Node v25.8.2, upng-js 2.1.0, ImageMagick. Le lot de 83 fichiers correspond à la totalité des PNG du répertoire public/og de ce site, et non à un échantillon prélevé dedans. Quatre fichiers de contrôle supplémentaires en 1200×630 et 800×600 couvrent séparément les cas photo, graphique, palette et JPEG.

1. La compression d’image ne fonctionne pas : un triage en trente secondes

Trouvez votre ligne, puis lisez la section vers laquelle elle pointe.

Ce que vous avez fourniCe que vous avez obtenuCause racineÀ lire
Capture d’écran ou graphique PNGPlus lourd que l’originalLe canvas l’a réencodé en RGBA 32 bitsSection 2
Photo JPEGPlus lourde que l’originalElle a été enregistrée en PNGSection 2
Photo JPEGPresque aucun changementDéjà à son palier de tailleSection 3
PNG déjà passé par un compresseurAucun changement, ou légèrement plus lourdPlus aucune marge disponibleSection 4
N’importe quoiPlus léger, mais flou ou aux couleurs fausséesPerte de génération, ou profil ICC suppriméSections 3 et 6

Ces lignes ne s’excluent pas mutuellement. Une photo JPEG déposée dans un exportateur PNG basé sur canvas déclenche les deux premières d’un coup, et c’est ainsi qu’un fichier de 47 828 octets se transforme en fichier de 809 415 octets.

Si vous voulez sauter le diagnostic et simplement récupérer un fichier plus léger, notre compresseur d’images utilise un encodeur PNG à quantification plutôt qu’un aller-retour par canvas, et il jette sa propre sortie chaque fois que le résultat n’est pas plus léger que ce que vous avez envoyé.

2. Cause n° 1 : le canvas du navigateur écrit toujours du RGBA 32 bits

Ce que canvas.toBlob() fait réellement à votre PNG

Un aller-retour par canvas décode puis réencode. Il n’y a aucune étape de compression au milieu, et tout ce qui n’est pas une valeur de pixel se perd au passage.

Dessinez une image sur un canvas et le navigateur la décode dans un tampon RGBA plat : quatre octets par pixel, pas de palette, pas d’astuce de profondeur de bits, pas de métadonnées. HTMLCanvasElement.toBlob() encode ensuite ce tampon en repartant de zéro. La spécification PNG définit six types de couleur, et un encodeur PNG est libre de retenir le moins coûteux de ceux qui représentent l’image. L’encodeur canvas de Chrome, lui, ne choisit pas. Il émet toujours le color type 6.

Type de couleur en entréeCe que canvas.toBlob('image/png') renvoie
RGB (color type 2)RGBA (color type 6)
Palette (color type 3)RGBA (color type 6)
JPEG (aucun type de couleur PNG)RGBA (color type 6)

Vous pouvez le lire directement dans les octets. L’octet 25 d’un fichier PNG porte la profondeur de bits et l’octet 26 le type de couleur, tous deux à l’intérieur du chunk IHDR :

xxd -s 24 -l 2 -p suspect.png
# 0806  ->  profondeur de bits 8, color type 6 (RGBA)

Les trois types d’entrée ci-dessus ont tous produit depth=8 type=6. Une image à palette de 64 couleurs stocke un octet par pixel plus une petite table ; après l’aller-retour, elle stocke quatre octets par pixel et la table a disparu. Deflate en récupère une partie, jamais la totalité.

Reproduisez le phénomène dans votre propre navigateur avec ce fragment à coller dans la console. Il choisit un fichier, lui fait faire l’aller-retour, puis affiche les deux tailles ainsi que le type de couleur :

const input = document.createElement('input');
input.type = 'file';
input.accept = 'image/png,image/jpeg';
input.onchange = async () => {
  const file = input.files[0];
  const bitmap = await createImageBitmap(file);
  const canvas = document.createElement('canvas');
  canvas.width = bitmap.width;
  canvas.height = bitmap.height;
  canvas.getContext('2d').drawImage(bitmap, 0, 0);
  const blob = await new Promise((r) => canvas.toBlob(r, 'image/png'));
  const head = new Uint8Array(await blob.slice(0, 26).arrayBuffer());
  console.log(file.name, file.size, '->', blob.size);
  console.log('bit depth', head[24], 'color type', head[25]);
};
input.click();

L’argument de qualité de toBlob est ignoré pour image/png. PNG est sans perte, il n’y a donc rien qu’un chiffre de qualité puisse sacrifier, et un curseur qui semble piloter la compression PNG dans un outil basé sur canvas ne pilote rien du tout.

83 fichiers mesurés : toutes les images compressées sont ressorties plus lourdes que l’original

Le test complet, sans tri sélectif :

MesureValeur
Fichiers testés83 (la totalité des PNG de public/og, types de couleur RGB et palette confondus)
Fichiers qui ont grossi83 / 83 (100 %)
Augmentation la plus faible+35,6 %
Augmentation médiane+76,6 %
Augmentation la plus forte+237,2 %

Un fichier, pour que vous en voyiez la forme : aes-decrypt.png est passé de 505 516 B à 898 014 B, soit une augmentation de +77,6 %. Le même fichier encodé en WebP en qualité 0.8 pèse 27 188 B, −94,6 %.

Ces 83 fichiers ont un profil très précis, et cela limite ce qu’on peut en tirer : ce sont des cartes Open Graph, 1200×630, fonds unis, gros texte, une poignée de couleurs de marque. C’est exactement le genre de graphique qu’un bon encodeur PNG traite bien, et c’est pour cela qu’un aller-retour par canvas leur fait autant de mal. Le résultat est solide pour les PNG de type graphique ; il ne prétend pas que tous les PNG du monde grossissent lors d’un aller-retour par canvas. Un PNG photographique déjà stocké en RGBA complet a beaucoup moins à perdre.

Ce qu’il établit en revanche : si votre image compressée est plus lourde que l’original et que l’outil tourne dans un onglet de navigateur, c’est l’encodeur qu’il faut regarder avant vos réglages.

Pourquoi un JPEG enregistré en PNG grossit de 16,9×

C’est le plus gros écart de tout le jeu de données. Quatre fichiers de contrôle, passés tous les quatre par le même chemin canvas :

FichierNatureOriginalPNG canvasVariationJPEG q92JPEG q80WebP q80
og-a.pngGraphique, 2 351 couleurs, RGB306 302607 481+98,3 %56 45937 69513 852
quantized.pngPalette de 64 couleurs59 843184 856+208,9 %78 38844 44216 046
photo.pngPhoto, 479 373 couleurs498 639867 763+74,0 %77 32145 05024 068
photo.jpgJPEG q8247 828809 415+1 592 % (16,9×)58 762 (+22,9 %)47 15223 862

Cette dernière ligne, c’est 47 828 octets en entrée, 809 415 octets en sortie.

Le mécanisme explique toute une famille de signalements du type « la compression a rendu mon fichier plus lourd ». JPEG est un codec avec perte qui travaille dans le domaine fréquentiel : il transforme des blocs de 8×8 en coefficients DCT, les quantifie agressivement et ne conserve que les survivants. PNG est un codec sans perte qui travaille dans le domaine spatial : il prédit chaque pixel à partir de ses voisins et compresse les résidus avec deflate. Décodez un JPEG et vous obtenez des pixels qui portent tous les artefacts introduits par le quantificateur : du ringing près des contours, un effet de blocs dans les dégradés doux, un bruit discret là où l’original n’en avait aucun.

Enregistrez ces pixels en PNG et vous demandez à un codec sans perte de stocker parfaitement ces artefacts. Il s’exécute. Le bruit même que JPEG a créé pour alléger le fichier devient ce qui alourdit le PNG, car c’est exactement ce qu’un encodeur sans perte prédictif ne sait pas compresser.

Partout où un réglage « enregistrer en PNG » par défaut se trouve devant une photo, c’est ce qui se produit : outils de capture d’écran, exports de logiciels de design, messageries, certains widgets d’envoi de fichiers.

Les mêmes pixels, 3,46× d’écart, les deux sans perte

L’encodeur canvas est faible, et l’écart se mesure. Prenez le tampon de pixels de og-a.png et encodez-le de deux façons, toutes deux entièrement sans perte :

EncodeurSortieType de couleur
Chrome canvas toBlob('image/png')607 481 BRGBA (suréchantillonnage forcé)
upng-js encode(..., cnum=0)175 491 BRGB (type de couleur d’origine conservé)

3,46×, pour des pixels identiques. Nous avons vérifié l’absence de perte au lieu de la supposer : décoder la sortie d’upng-js en cnum=0 renvoie un tampon octet pour octet identique au tampon RGBA d’entrée. On ne sacrifie rien pour obtenir ce 3,46×.

Cela explique pourquoi deux compresseurs en ligne gratuits qui annoncent la même chose donnent des résultats sans commune mesure : « compresser dans le navigateur » recouvre deux implémentations complètement différentes. L’une confie les pixels à canvas.toBlob et livre ce qui en ressort. L’autre embarque un véritable encodeur PNG et contrôle le type de couleur. Même entrée, même navigateur, 3,46× d’écart.

3. Cause n° 2 : votre JPEG n’a plus rien à donner

Cinq passes de recompression, et la taille cesse de bouger

Prenez photo.jpg, déjà enregistré en qualité 82, et recompressez-le cinq fois de suite en qualité 0.8, chaque génération alimentant la suivante :

GénérationOctetsvs. précédente
0 (original, q82)47 828
147 152−1,4 %
247 164+0,0 %
347 156−0,0 %
447 1560,0 %
547 1560,0 %

La première passe vous rapporte 1,4 %. À partir de la génération 2, la taille du fichier est verrouillée dans une bande de ±12 octets, et les générations 4 et 5 pèsent exactement le même nombre d’octets que la génération 3.

Voilà à quoi ressemble « la compression ne fonctionne pas » quand l’entrée est un JPEG. L’outil a tourné. L’encodeur a tourné. Il n’y avait tout simplement plus rien à retirer, parce que les tables de quantification de la qualité 80 mettaient déjà à zéro à peu près les coefficients que la qualité 82 avait conservés. Une fois qu’un coefficient a disparu, on ne peut pas le retirer une deuxième fois.

Vous pouvez observer le phénomène en local :

cp photo.jpg gen0.jpg
for i in 1 2 3 4 5; do
  magick "gen$((i-1)).jpg" -quality 80 "gen$i.jpg"
done
stat -f%z gen0.jpg gen1.jpg gen2.jpg gen3.jpg gen4.jpg gen5.jpg

Sous Linux, utilisez stat -c%s à la place. Le décompte exact des octets dépend de l’encodeur auquel votre build d’ImageMagick est lié, n’attendez donc pas du tableau ci-dessus qu’il se reproduise chiffre pour chiffre. C’est la forme qui compte : une baisse significative, puis une ligne plate.

Monter le paramètre de qualité, ce n’est pas compresser

Regardez de nouveau la ligne photo.jpg de la section 2. Recompresser cet original de qualité 82 en qualité 92 a produit 58 762 octets : +22,9 %.

Cela surprend ceux qui prennent le paramètre de qualité pour un cadran allant de « petit » à « grand », qu’ils seraient libres de régler où bon leur semble. Ce n’est pas une cible de qualité absolue. Il sélectionne une table de quantification, et repasser une image décodée dans une table plus fine que celle qui l’a produite stocke plus précisément les artefacts existants tout en ajoutant une nouvelle couche de perte par-dessus. Fichier plus lourd, image moins bonne, les deux à la fois.

La règle qui en découle : ne recompressez jamais un JPEG à un réglage de qualité supérieur à celui avec lequel il a été enregistré. Si vous ignorez quel était ce réglage, ne recompressez pas du tout. Revenez à la source.

Perte de génération : la dégradation de qualité invisible de la recompression JPEG

Le tableau du palier cache un piège. La taille a cessé de changer après la génération 2, mais l’image, elle, a continué de changer. Chaque passe décode en pixels, retransforme et requantifie. Des coefficients qui survivaient de justesse à une génération basculent de l’autre côté à la suivante.

Les dégâts n’apparaissent pas là où vous les cherchez. En taille de vignette, les générations 5 et 1 sont impossibles à distinguer. Zoomez à 100 % et allez voir les endroits où JPEG lâche toujours en premier : les contours nets sur fond uni, le texte, et les dégradés doux où l’effet de blocs se manifeste par des tuiles 8×8 visibles. Dans une chaîne de build qui recompresse à chaque déploiement, cela s’accumule en silence pendant des mois.

Nous avons mesuré ici des tailles de fichiers, pas de la qualité perçue, nous n’allons donc pas vous citer un PSNR ou un SSIM pour les cinq générations : nous ne les avons pas mesurés. Les données de taille suffisent à établir ceci, et rien de plus : à partir de la génération 2, le coût est entièrement du côté de la qualité et le bénéfice est nul.

Les dérives de couleur sont un échec différent, avec le même déclencheur. Le canvas ne transporte aucune métadonnée, si bien qu’un aller-retour par toBlob supprime le bloc EXIF et, avec lui, le profil ICC. Une image marquée Display P3 ou Adobe RGB à l’entrée ressort sans balise, ce que les visionneuses interpréteront comme du sRGB. Les valeurs des pixels n’ont pas bougé. Les instructions pour les interpréter, si.

4. Cause n° 3 : la taille du PNG ne baisse pas parce qu’il a déjà été quantifié

Si votre PNG est déjà passé une fois par un compresseur, la deuxième passe n’a plus de matière. C’est la ligne quantized.png, un fichier de 59 843 octets déjà réduit à une palette de 64 couleurs, poussé dans trois chemins distincts :

CheminRésultatvs. original
Réencodage sans perte (upng cnum=0)61 377+2,6 %
Quantification à 256 couleurs61 366+2,5 %
Quantification à 64 couleurs61 366+2,5 %

Tous les chemins sont ressortis plus lourds que l’original. Pas de beaucoup, mais plus lourds, et cela vaut aussi pour la quantification à 64 couleurs d’un fichier qui comptait déjà 64 couleurs.

La compression PNG fonctionne en supprimant la redondance : couleurs répétées, voisins prévisibles, petite palette. Une passe précédente a déjà tout ramassé. Ce qui reste est proche de l’incompressible, et la minuscule augmentation correspond à la surcharge propre à l’encodeur : un ordre de palette légèrement différent, d’autres choix de filtre ligne par ligne, un deflate un peu moins chanceux.

En pratique, « 0 % économisé » sur un PNG déjà optimisé est le bon résultat, pas un échec. Un outil qui signale une légère augmentation puis conserve votre fichier d’origine se comporte correctement. Un outil qui vous remet quand même le fichier plus lourd, non.

5. Pour le PNG, le vrai levier est la quantification, pas le réencodage

Réencodage sans perte contre 256 couleurs contre 64 couleurs

Trois fichiers passés par trois stratégies :

FichierOriginalSans perte (cnum=0)256 couleurs64 couleurs
og-a.png306 302175 491 (−42,7 %)110 772 (−63,8 %)76 230 (−75,1 %)
photo.png498 639587 863 (+17,9 %)109 284 (−78,1 %)61 397 (−87,7 %)
quantized.png59 84361 377 (+2,6 %)61 366 (+2,5 %)61 366 (+2,5 %)

Le réencodage sans perte est l’outil le plus faible dont on dispose. Il a gagné 42,7 % sur le graphique, rendu 17,9 % sur la photo et perdu 2,6 % sur le fichier déjà quantifié. Le contenu photographique met en échec même un encodeur PNG sans perte compétent, parce qu’il n’y a pas de palette à trouver et que les pixels voisins se prédisent mal les uns les autres.

C’est la quantification qui fait baisser la taille, et l’écart n’est pas serré : 63,8 % contre 42,7 % sur le même graphique à 256 couleurs, 75,1 % à 64. En ligne de commande :

magick logo.png -colors 64 PNG8:logo-64.png
magick logo.png -colors 256 PNG8:logo-256.png

Le préfixe PNG8: force un PNG à palette. Sans lui, ImageMagick peut réduire les couleurs puis écrire malgré tout un fichier truecolor, ce qui gaspille l’essentiel du bénéfice.

Quand une palette passe sans dommage, et quand des bandes apparaissent

La quantification est une opération avec perte. Elle rattache chaque pixel à l’entrée la plus proche dans une palette limitée ; reste à savoir si votre contenu contient assez de couleurs distinctes pour que cela se voie.

Sans risque : icônes, logos, captures d’interface, illustrations à plat, diagrammes, tout ce qui présente de grandes zones de couleur uniforme et des contours nets. Ces contenus comptent en général quelques centaines de couleurs distinctes tout au plus, une palette de 256 entrées y est donc quasiment gratuite et même 64 s’en sort souvent.

À risque : photographies, dégradés doux, ombres portées floues et calques semi-transparents. Réduire un dégradé à 64 paliers produit des bandes visibles, et le tramage échange ces bandes contre un bruit qui vous reprend ensuite une partie du gain de taille. La transparence partielle sur un dégradé est le cas le plus difficile de tous.

La transparence mérite sa propre vérification, parce que la quantité qui en survit dépend de l’encodeur plutôt que de la quantification elle-même. Le PNG8: d’ImageMagick écrit une transparence binaire : un pixel est soit totalement opaque, soit totalement transparent, et un bord anticrénelé doux ressort dur. Un quantificateur PNG dédié conserve le canal alpha complet, et le bord doux avec. Si votre visuel comporte une ombre portée ou des bords adoucis, comparez les deux avant de vous engager.

Contrôlez le résultat à 100 %, pas dans une vignette. Les bandes sont l’artefact que l’aperçu réduit masque le plus fidèlement.

6. Le correctif : changer de format au lieu de recompresser

Une table de décision des formats

ContenuÀ utiliserPourquoi
PhotographiesWebP, ou JPEG pour une compatibilité maximaleLe codage fréquentiel avec perte est ce dont les photos ont besoin
Captures d’écran, graphiques d’interfacePNG quantifié, ou WebPCouleurs à plat, contours nets, petites palettes
Icônes et logosSVG quand vous disposez du vectoriel, sinon PNG quantifiéLes vecteurs n’ont pas de problème de résolution
Tout ce qui exige de la transparenceWebP ou PNGLes deux transportent un canal alpha complet
AnimationWebPUn seul format au lieu d’un GIF
Archivage au pixel prèsPNG, sans perteLe seul cas où le sans-perte est une exigence

C’est la version courte, délibérément. L’efficacité d’encodage et la prise en charge par les navigateurs des formats modernes ont leur propre article : WebP vs AVIF vs JPEG.

Ce que WebP a donné sur les mêmes 83 fichiers

Le lot de 83 fichiers qui a grossi dans 100 % des cas via le PNG canvas, converti cette fois en WebP en qualité 0.8 : 83 sur 83 ont diminué, médiane −94,2 %. Le fichier isolé cité plus haut, aes-decrypt.png, est passé de 505 516 B à 27 188 B, −94,6 %.

Les fichiers de contrôle vont dans le même sens. og-a.png : 306 302 en PNG, 13 852 en WebP q80. photo.png : 498 639 en PNG, 24 068 en WebP q80. photo.jpg : 47 828 en JPEG, 23 862 en WebP q80.

Une réserve sur cette dernière comparaison. WebP en qualité 0.8 est un format avec perte, il ne joue donc pas à armes égales avec PNG, et réencoder un JPEG existant en WebP vous coûte quand même une génération. Comparez avec ce que vous étiez sur le point de livrer, pas avec un hypothétique original parfait.

Quand vous devez tout de même garder le PNG

Certains usages imposent le sans-perte. Gardez le PNG pour les visuels qui repartent dans une chaîne de design et seront réédités, pour les captures d’écran servant aux tests de comparaison au pixel près, pour les découpes d’interface où une seule couleur décalée casse un diff visuel, et pour tout ce qui sera composité plus tard, où les artefacts de quantification se cumuleraient. Dans ces cas-là, faites tourner un vrai encodeur à quantification si le contenu le permet, et acceptez la taille du fichier s’il ne le permet pas.

Encore un type de « plus lourd » qui n’a rien à voir avec la compression

Si vous intégrez vos images en data URI, la taille dans votre CSS ou votre HTML n’est pas la taille sur le disque. Base64 encode chaque groupe de 3 octets en 4 caractères, plus le padding, si bien que le texte est arithmétiquement +33 % plus volumineux que les octets qu’il transporte, avant toute compression de transfert. Une image parfaitement optimisée gagne quand même un tiers dès l’instant où vous l’intégrez. Notre guide de l’inlining en data URI détaille quand ce compromis vaut la peine.

7. En pratique : navigateur, ligne de commande, chaîne de build

Dans le navigateur

Au moment de choisir un outil basé sur le navigateur, vérifiez si le PNG passe par canvas. Dans notre compresseur d’images, ce n’est pas le cas. Le PNG en entrée est quantifié sur une palette de couleurs puis réécrit en véritable PNG avec son canal alpha intact : la transparence et les bords doux survivent. Le curseur de qualité pilote une taille de palette plutôt qu’un argument de toBlob que le PNG ignorerait de toute façon. La qualité 100 correspond à un réencodage sans perte. Les fichiers JPEG et WebP, eux, passent bien par canvas, où le paramètre de qualité est réel et fait ce que vous attendez de lui.

Le comportement suivant ressemble à un bug sans en être un : si le résultat compressé n’est pas plus léger que le fichier que vous avez envoyé, l’outil jette sa propre sortie et conserve vos octets d’origine. Sur un PNG déjà optimisé, vous verrez « 0 % économisé ». C’est la section 4 qui fonctionne comme prévu.

Tout se passe dans votre navigateur ; aucun octet ne part vers un serveur.

En ligne de commande

cwebp est livré avec libwebp et c’est le moyen le plus rapide de tester si un changement de format résout votre problème :

# WebP avec perte, qualité 0-100
cwebp -q 80 photo.png -o photo.webp

# WebP sans perte, effort de compression 0-9
cwebp -z 9 logo.png -o logo.webp

ImageMagick 7 couvre les cas de conversion et de quantification :

# PNG vers JPEG à une qualité choisie
magick photo.png -quality 80 photo.jpg

# Quantifier vers un PNG à palette de 64 couleurs
magick logo.png -colors 64 PNG8:logo-64.png

# Supprimer l'EXIF et les autres métadonnées
magick photo.jpg -strip photo-clean.jpg

Sous macOS, sips est déjà installé et ne réclame aucune dépendance :

# Convertir en JPEG ; formatOptions accepte 0-100 ou low/normal/high/best
sips -s format jpeg -s formatOptions 80 photo.png --out photo.jpg

# Redimensionner pour que le plus grand côté fasse 1200 px, ratio préservé
sips -Z 1200 photo.jpg --out photo-1200.jpg

# Relire les dimensions
sips -g pixelWidth -g pixelHeight photo-1200.jpg

Redimensionnez avant de compresser. Les encodeurs travaillent sur des pixels, et le pixel le moins cher est celui qui n’existe pas.

Dans une chaîne de build

Dès que l’opération devient automatisée, la question se déplace vers l’endroit où le travail s’effectue et vers la bibliothèque qui s’en charge. Les arbitrages changent complètement, et compression d’images côté navigateur ou côté Node.js traite cette comparaison. La seule règle de cet article qui se transpose telle quelle : compressez à chaque build à partir du fichier source d’origine, jamais à partir de la sortie du build précédent. C’est ainsi qu’une chaîne descend toute seule la courbe de la perte de génération pendant que les tailles de fichiers paraissent parfaitement stables.

8. Cinq croyances que les mesures ne soutiennent pas

« Compresser deux fois donne un fichier plus léger. » La génération 1 a rapporté 1,4 %. Les générations 2 à 5 sont restées dans une bande de ±12 octets pendant que l’image continuait de se dégrader. La deuxième passe est un coût pur.

« PNG est sans perte, c’est donc le meilleur format. » Le sans-perte est une propriété, pas une vertu. Notre photo de test pèse 498 639 octets en PNG et 24 068 en WebP q80. Préserver une photographie au bit près alors qu’elle ne sera jamais vue qu’à l’écran n’apporte rien et coûte l’essentiel du fichier.

« La qualité 100 est le choix prudent. » Recompresser un JPEG de qualité 82 en qualité 92 a produit +22,9 % et une image moins bonne. Au-dessus du réglage de qualité de l’original, le chiffre cesse de vouloir dire « plus sûr » et se met à vouloir dire « plus lourd ».

« Le fichier est lourd parce que la résolution est élevée. » La résolution compte, mais à résolution égale, c’est le format qui pèse le plus. og-a.png fait 1200×630 dans les deux cas : 607 481 octets en PNG canvas, 13 852 octets en WebP q80. Nombre de pixels identique.

« Les compresseurs en ligne se valent tous. » Mêmes pixels, même navigateur, les deux sans perte : 607 481 octets depuis canvas, 175 491 depuis upng-js. Un écart de 3,46× entre deux outils qui se décrivent de façon identique.

9. FAQ

Pourquoi mon image compressée est-elle plus lourde que l’original ?

Parce que l’outil l’a réencodée au lieu de la compresser. La sortie du canvas du navigateur est toujours un PNG RGBA 32 bits, ce qui supprime les palettes et stocke quatre octets par pixel. Dans notre test portant sur 83 PNG réels, les 83 ont grossi, avec une augmentation médiane de +76,6 %. Convertissez plutôt en WebP ou en JPEG.

Pourquoi mon PNG ne devient-il pas plus léger quand je le compresse ?

PNG est sans perte, un curseur de qualité n’a donc rien à sacrifier. La réduction vient de la baisse du nombre de couleurs, et si le fichier avait déjà été quantifié, il ne reste plus rien à couper. Notre PNG de test à 64 couleurs est ressorti à +2,5 % après avoir été quantifié une seconde fois à 64 couleurs.

Compresser un JPEG deux fois dégrade-t-il la qualité ?

Oui, et vous n’obtenez presque rien en échange. Cinq passes en qualité 0.8 : 47 828 octets ramenés à 47 152 dès la première passe, puis verrouillés dans une bande de 12 octets pour les quatre suivantes. La taille a cessé de bouger tandis que chaque passe continuait de requantifier l’image. Gardez vos originaux.

PNG ou JPEG pour obtenir un fichier plus léger ?

Pour les photographies, JPEG ou WebP, sans exception. Notre photo de test mesure 498 639 octets en PNG, 45 050 en JPEG q80 et 24 068 en WebP q80. Réservez PNG aux graphiques à plat, au texte net et à la transparence, là où une petite palette fait le travail de compression.

Pourquoi mon image est-elle devenue floue après compression ?

Deux causes distinctes. Les encodeurs avec perte réglés sur une qualité basse produisent un effet de blocs visible autour des contours et du texte. Les passes répétées ajoutent de la perte de génération même quand la taille du fichier cesse de changer. Si les couleurs ont dérivé au lieu de s’adoucir, c’est l’aller-retour par canvas qui a supprimé votre profil ICC, puisque le canvas ne transporte aucune métadonnée.

Peut-on compresser une image sans perdre en qualité ?

Oui, mais attendez-vous à bien moins. Le réencodage sans perte se contente de réécrire plus efficacement des pixels identiques : 306 302 à 175 491 octets sur notre graphique, vérifiés octet pour octet identiques après décodage. La même approche sur une photo est partie dans le mauvais sens, +17,9 %. Pour des économies sérieuses sans perte visible, utilisez WebP en qualité 80.

Pourquoi mon PNG est-il si volumineux alors que ce n’est qu’une capture d’écran ?

Les captures d’écran sont stockées en PNG RGBA complet, quatre octets par pixel avant compression, et un écran Retina double le nombre de pixels dans chaque dimension. Le contenu à plat réagit bien à la réduction de palette : notre graphique de carte Open Graph a perdu 63,8 % à 256 couleurs et 75,1 % à 64.

Le redimensionnement réduit-il la taille du fichier plus que la compression ?

En général oui, et les deux se cumulent. Diviser les deux dimensions par deux retire les trois quarts des pixels avant même que l’encodeur ne démarre, et la taille du fichier suit globalement le nombre de pixels. Redimensionnez d’abord aux dimensions que vous affichez réellement, puis compressez une seule fois. Un fichier d’appareil photo en pleine résolution déposé dans un emplacement de vignette gaspille les deux passes.

Tags: image-compression png jpeg webp canvas debugging

Articles connexes

Voir tous les articles