summaryrefslogtreecommitdiff
path: root/articles/formats-images-web.md
blob: 57b9d638f44ff97822281901856a4ea837d3aa69 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
---

pubDate = 2023-08-11
tags = ['web', 'image', 'programmation']

[author]
name = "ache"
email = "ache@ache.one"

[[alt_lang]]
lang = "en"
url = "/articles/web-image-formats"

---

<script>
window.addEventListener('load', () => {
    const iframeImages = document.querySelectorAll('.iframe-img');
    for(const img of iframeImages) {
        const imgSrc = img.getAttribute('src')
        const iframeSrc = imgSrc.slice(0, imgSrc.lastIndexOf('.png')) + '.html';

        fetch(iframeSrc)
        .then(response => response.text())
        .then(html => {
            let fullDiv = document.createElement('DIV');
            fullDiv.innerHTML = html;
            const oldDiv = fullDiv.getElementsByClassName('plotly-graph-div')[0];
            const oldSCript = fullDiv.getElementsByTagName('script')[0];

            const script = document.createElement('SCRIPT');
            const div = document.createElement('DIV');
            div.innerHTML = oldDiv.outerHTML;
            div.style.height = "700px";
            div.classList.add("big");
            script.text = oldSCript.text;

            img.parentElement.replaceWith(div);
            div.appendChild(script);
        }).catch(err => {
            console.warn('Something went wrong.', err);
        });
    }
});
</script>


Étude des formats d'images
==========================

![Illustration d'un format d'image AVIF, JXL ou JPEG](/s/imgM/image-formats.svg)
Quels formats d'images utiliser de nos jours ?
Dans cet article, étudions les formats d'images modernes, (AVIF, HEIF, WebP, WebP2 et JPEG XL) le plus justement possible. 🖼️

D'abord, je vais présenter comment j'ai étudié ces formats d'images.
Puis je ferais une comparaison des encodeurs.
Ensuite, j'analyserais les données récoltées de manière la plus complète possible.
Enfin, à partir de l'analyse des données, on comparera les formats d'images et leur cas d'utilisation.

:::note
Cet article va être long et technique. N'hésitez pas à aller directement à la partie analyse, ou même à la conclusion.
:::

Sommaire
--------

Protocole d'étude
----------------

J'ai constitué un jeu d'images *libres de droits* trouvées sur le web.
Ce jeu de donnée est constitué d'images de dimensions, de tailles, d'origines et d'usages très variés.
Au total, ce sont 169 images issues de 6 jeux de données différents qui ont été analysées.

Chaque encodeur converti les images en faisant variées, pour chaque image, les options de vitesses (parfois appelé effort) et de qualité.
Ainsi pour **chaque image**, 308 images ont été produites.

Puisque les formats étudiés utilisent tous des compressions à perte, il est nécessaire d'estimer la qualité perdue lors du processus d'encodage.
Chaque image produite a ainsi été décodée vers le format PNG.
Celle-ci a servi à calculer la similarité structurelle afin de pouvoir estimer la perte de qualité induite par l'encodeur. [^DSSIM]

[^DSSIM]: [L'implémentation (en Rust) utilisée](https://kornel.ski/dssim) est celle de [Kornel](https://mastodon.social/@kornel), que je remercie.

Pour chaque image les données récoltées de ce processus sont:

 - [x] Si le processus d'encodage a réussi (Code de retour de l'encodeur égal à 0).
 - [x] Le nom de l'image et de son jeu de données.
 - [x] Le format de l'encodeur ainsi que les paramètres de qualité et d'effort (vitesses de compression) utilisés par l'encodeur.
 - [x] La taille de l'image source et de l'image cible afin de calculer le taux de compression.
 - [x] Le temps d'encodage et de décodage de l'image cible.
 - [x] La mesure de similarité[^dis] structurelle.
 - [x] La date à laquelle l'image a été générée.

[^dis]: Techniquement, un calcul de dissimilarité. Ici, on cherche les similarités dites structurelles entre deux images par l'algorithme [SSIM](https://fr.wikipedia.org/wiki/Structural_Similarity).
C'est une des méthodes d'estimation de la différence de perception entre deux images.


### Résultats attendus

Je m'attends à ce que WebP soit moins performant que les autres formats sur tous les points.
Aussi, AVIF devrait être moins performant que WebP2.
Si on en croit le retrait du support de JPEG XL dans Chrome et Firefox, je m'attends à ce que JPEG XL soit moins performant que WebP2 et n'apporte que peu par rapport à AVIF.


### Le jeu de données

J'ai constitué moi-même ce jeu de données.
Je ne possède pas les droits sur les images, mais j'ai privilégié des images libres de droit quand c'était possible.
J'ai privilégié la variété à la liberté d'utilisation.
Un jeu de données totalement libre aurait pu être constitué mais m'aurait demandé beaucoup plus de temps.
Bien que je trouve ça ridicule, techniquement, je possède un droit sur le jeu de données.
Je vous informe donc que vous êtes libre de le réutiliser et de le modifier tant que vous respectez les licences originales des images.

Vous pouvez le télécharger depuis ce [fichier torrent](res/datasets_test_imgs_ache.torrent) ou ce [lien magnet 🧲](magnet:?xt=urn:btih:3217ff465d9c13cdbb2f7b1d776ee0f2a152ba54&dn=datasets_test_imgs_ache&tr=udp://tracker.opentrackr.org:1337/announce&tr=https://tracker1.520.jp/announce&tr=udp://tracker.torrent.eu.org:451/announce&tr=http://bt.endpot.com/announce).

Jeu de données | Format | Nombre d'images | Description | Droits d'utilisation
---------------|----------------|-----------------|-------------|--------------------
low_def_imgs_set_jpg | jpg | 39 | Sous-ensemble du [jeu de données de l'USC-SIPI](https://sipi.usc.edu/database/).[^USC-SIPI] | Complexes mais [admis qu'on peut les utiliser à des fins de recherche](https://sipi.usc.edu/database/copyright.php)
png_random | png | 38 | Des images PNG variées issues d'une expérience de quelques heures sur internet. Une sélection a été faite afin de ne pas avoir trop d'images similaires. | Un mixe de « libre pour un usage personnel »,  CC et certainement partagée avec une licence restrictive.
photos_imgs_set_jpg | jpg | 16 | Photos personnelles de vacances et de voyage. | Je possède les droits et j'autorise l'utilisation sous licence CC-BY 2.0 ache.
high_def_imgs_set_jpg | jpg | 28 | Images de qualité professionnelle et libres de droit issues du site Pexels. L'attribution de chaque image est donnée dans le nom de la photo. | [Libre d'utilisation](https://www.pexels.com/license/)
selected_holliday _photos_jpg | jpg | 24 | Sous-ensemble du [jeu de données de l'INRIA](https://lear.inrialpes.fr/~jegou/data.php#holidays). | Propriété de l'INRIA[^source_inria]. Usage conditionné au fait de citer le papier dont il est issu.
xkcd | png | 24 | Sous-ensemble de planche de la bande dessinée en ligne XKCD. | [CC-BY-NC](https://xkcd.com/license.html)

[^USC-SIPI]: Images de faible résolution, principalement issues de la catégorie *divers* (misc).
[^source_inria]: Issue de l'article « Hamming Embedding and Weak geometry consistency for large scale image search », présenté à la 10ᵉ conférence européenne de vision par ordinateur en octobre 2008.


### Les encodeurs

J'ai utilisé une version précise des encodeurs, la plus récente disponible.
Cela améliore la reproductibilité de l'expérience.

Format | Support de la transparence | Intervalle de qualité | Intervalle d'effort | Encodeur / Décodeur | Version
-----|---|-------|---------------------|-----------------------|------
AVIF | ✔️ | 0-100 | Option indisponible | heic-enc / heic-convert | 1.15.2
HEIF | ✔️ | 0-100 | Option indisponible | heic-enc / heic-convert | 1.15.2
JXL  | ✔️ | 0-100 | 1-9[^zap]           | cjxl / djxl             | v0.8.1 (c27d4992)
WebP | ✔️ | 0-100 | 0-7                 | cwebp / dwebp           | 1.3.0 (libsharpyuv: 0.2.0)
WebP2 | ✔️ | 0-100 | 0-10               | cwp2 / dwp2             | 0.0.1 (b80553d)

[^zap]: Chaque niveau d'effort possède une représentation textuelle et je trouve ça très drôle.

    Niveau | Textuelle | Traduction
    --|---|----
    1 | lightning | lumière ⚡
    2 | thinder   | tonnerre 🌩️
    3 | falcon    | faucon
    4 | cheetah   | guépard
    5 | hare      | lièvre
    6 | wombat    | wombat
    7 | squirrel  | écureuil 🐿️
    8 | kitten    | chat 😸
    9 | Tortoise  | tortue 🐢

Il est à noter que les formats et encodeurs ne proposent pas tous les mêmes fonctionnalités.
AVIF ni WeBP2 ne proposent pas par exemple le décodage progressif.
Je n'ai cependant jamais activé cette option dans l'encodeur cjxl.

Lorsque cela a été possible, j'ai activé le calcul parallèle, c'est-à-dire avec WebP et WebP2.
Pour WebP2 j'ai limité à 8 le nombre de fils d'exécution alors que WebP ne proposait pas cette option.

De même, les paramètres entre encodeur ne sont pas comparables ! ⚠️  
Ainsi `50` de qualité pour AVIF **ne correspond pas** à `50` de qualité pour WebP2.

:::note
Une erreur de ma part a été d'inclure la qualité 100 de JPEG XL qui active automatiquement son mode compression sans perte alors que les autres encodeurs ont besoin d'une option pour ça.
:::


#### Support des navigateurs

En aout 2023, date d'écriture de cet article:

 - WebP bénéficie du meilleur support
 - AVIF possède également un très bon support mais Edge et certains autres navigateurs plus confidentiels rechignent à le supporter.
 - JXL n'est supporté que pas Safari mais le support a existé de manière expérimentale sur Chrome et Firefox.
 Il a été retiré de Chromium.
 Pour Firefox, il n'est présent qu'en _nightly_ en activant l'option `image.jxl.enabled`.
 - HEIF est supporté par les versions modernes de Safari.
 - WebP2 n'a aucun support.

<img alt="Support de WebP par les différents navigateurs" class="big" loading="lazy" src="res/support_webp.png">

<br>

<img alt="Support de AVIF par les différents navigateurs" class="big" loading="lazy" src="res/support_avif.png">

<br>

<img alt="Support de JPEG XL par les différents navigateurs" class="big" loading="lazy" src="res/support_jxl.png">

Support des différents formats disponible actuellement sur le site [canisuse.com](https://caniuse.com/).


#### Fonctionnalités

Format | Animation | HDR | Décodage progressif | Nombre maximum de chanaux | Dimensions maximales
-------|-----------|-----|---------------------|---------------------------|--------------------
WebP  | ✔️ | ✖️      | ✖️  | 4    | 16 383 x 16 383       |
AVIF  | ✔️ | 10bits | ✖️  | 5    | 8193x4320      |
JXL   | ✔️ | 12bits | ✔️  | 5    | 1 703 741 823 x 1 703 741 823 |
WebP2 | ✔️ | 10bits | 🤷 | 4099 | 16 383 x 16 383 |

AVIF supporte des dimensions arbitraires mais alors l'image est découpée en blocs de 8193x4320.
Aucune cohérence n'est assurée à la liaison entre ces blocs, ce qui peut provoquer des artéfacts.

Il est prévu de supporter le décodage incrémental dans le README de l'encodeur de WebP2.
Est-ce synonyme de décodage progressif ? Certainement.
Est-ce déjà implémenté ? Je n'en sais rien.


Analyse des images produites
----------------------------

On va analyser les erreurs, puis les performances de chaque encodeur.

### Les erreurs d'encodage 🐛 🐞

Il existe deux types d'erreurs:
 1. Lorsque le processus d'encodage plante ou échoue et retourne ainsi un code d'erreur différent de 0.
 1. Lorsque qu'à l'issue du processus d'encodage, l'image générée est particulièrement différente de l'image source.
    Je vais poser arbitrairement un seuil de `0.4` de similarité[^dis], ainsi toute image ayant un seuil DSSIM supérieur sera considérée comme en erreur.


#### Encodeur heic-enc des formats AVIF et HEIF

L'encodeur heic-enc a un problème de gestion des données EXIF, l'image n'est pas correctement retournée.
Ainsi, le calcul de la similarité structurelle n'a pas pu fonctionner, les images originales et produites n'ayant pas les mêmes dimensions.
Cette erreur affecte le format AVIF et HEIF.
Afin de gérer ce cas, les données EXIF ont été supprimées pour tous les images.
Cela ne devrait pas affecter la taille de l'image produite.
Cette erreur ayant été contournée, elle n'a pas été comptabilisée comme une erreur.


Également sur certain PNG l'image produite était particulièrement différente de l'image source.
Cela semble être un problème de décodage de l'image source puisque les deux formats sont affectés.
De plus l'image produite est reconnaissable mais fortement détériorée.
9 images sources sont affectées, l'erreur est systématique sur chaque image produite depuis ces images sources.


#### Encodeur cjxl

L'encodeur jxl réussi toujours mais l'étape de décodage a échoué 3 fois.
Ceci laisse à penser que **jxl n'a pas produit une image valide**.
C'est en quelque sorte le pire bug possible.
En testant avec [une autre implémentation de decodeur JPEG XL](https://github.com/tirr-c/jxl-oxide), on obtient une erreur plus explicite « Unexpected end of file ».

Il y a également eu 3 images générées qui sont particulièrement différentes de l'image source.
Cependant, contrairement a l'encodeur heic-enc, cette erreur se produit uniquement lorsque les images sont encodées avec une qualité de 100 et un effort de niveau 1, nommé lightning ⚡.
Les 3 images affectées par ce bug sont méconnaissables mais curieusement, le set de couleurs utilisées est reconnaissable.
On peut noter que ces 3 images ont également été des images qui n'ont pas été représentées fidèlement par heic-enc.
Il est peu probable que ça soit une coïncidence mais c'est possible.


#### Encodeur cwebp et cwp2


L'encodeur WebP echoue sur 6 images et celui de WebP2 sur 1 images.

L'erreur d'encodage de WebP2 est claire : `WP2_STATUS_BAD_DIMENSION`.
En effet l'image en question est effectivement de dimension particulièrement grande.
C'est la seule erreur.

L'encodeur de WebP échoue sur la même image, pour la même raison, mais également sur 5 autres images.
Dans ces cas l'erreur retournée est :

~~~
Saving file 'test_crash.webp'
Error! Cannot encode picture as WebP
Error code: 6 (PARTITION0_OVERFLOW: Partition #0 is too big to fit 512k.
To reduce the size of this partition, try using less segments with the -segments option, and eventually reduce the number of header bits using -partition_limit. More details are available in the manual (`man cwebp`)
~~~

Étant donné que l'erreur ne se produit qu'avec simultanément une qualité à 90 ou 100 et un effort à 0 ou 1, je considère ceci comme un cas limite que l'encodeur a du mal à gérer.
Je n'ai pas plus investigué.

Je note que, pour ces deux encodeurs, il n'y a pas d'erreur de similarité trop faible entre l'image produite et l'image source.
C'est une très bonne chose. 👌


#### Conclusion de l'étude des erreurs

Seul le format JPEG XL échoue à encoder des images et produit des glitchs.
La partie décodage des images PNG de `heic-enc` doit être améliorée, elle présente de **très nombreux bugs** qui produisent également des glitchs.
Les formats WebP et WebP2 posent des problèmes au niveau des dimensions limitées supportées par le format.
WebP présente un bug dans son implémentation officielle dans certains cas limites.

À partir de maintenant, on va exclure les cas présentant des erreurs de nos statistiques.
Ainsi, AVIF et HEIF auront 9 images en moins.
JPEG XL, WebP et WebP2 n'auront pas de données correspondant à certains paramètres.

Les bugs rencontrés par JPEG XL ont été résolus désormais mais le correctif n'est pas encore disponible dans la dernière version publiée.
J'ai alerté du [bug d'encodage de heif-enc](https://github.com/strukturag/libheif/issues/937).
Je n'ai pas fait la même chose pour WebP, le processus nécessitant un compte Google.


### Taux de compression comparé à la qualité de l'image produite

Pour facilité les comparaisons, je vais *comparer par jeux de données*.
Ils se trouvent qu'effectivement beaucoup d'images d'un même jeu de données suivent les mêmes tendances.
Je vais donc essayer de lister les différentes tendances.


#### Images basses définition

Au sein du jeu de données `low_def_imgs_set_jpg` on retrouve 3 tendances.
Un petit ensemble d'images où les formats AVIF et HEIF s'en sortent particulièrement mal, 3 images où la variation des performances est très grande et le reste où tous les formats d'images ont des performances équivalentes à peu près.

Dans environ 13 cas, les formats AVIF et HEIC sont moins performants que tous les autres.
La similarité maximale atteinte est éloignée de 0.
À la vue des images, il ne semble pas que les images concernées aient un point commun évident.
On peut soit expliqué ces faibles performances par un problème de décodage soit que les algorithmes ne sont pas efficaces sur ces images.

Sur 3 images, il est clair que les résultats sont très variés. Les performances de chaque format dépends beaucoup de l'effort et de la qualité configurée.
Malgré les fortes variations, il y a une segmentation claire où WebP2 est clairement plus performant que ses concurrents.
AVIF et HEIC sont correctes mais JPEG XL est à la traine derrière WebP.
Les images concernées sont clairement des images de tests en niveau de gris.

Enfin, pour le reste des images de faible résolution, on constate que les performances de tous les formats d'images sont à peu près identiques.
Seul WebP est légèrement à la traine.


#### PNG aléatoires

Ici, il n'est pas évident de définir une tendance.
De manière générale, AVIF équivaut à WebP2 et font tous deux mieux que JPEG XL.
WebP est généralement plutôt mauvais, mais il n'est pas rare qu'il égale JXL en performance.
Mais ce n'est présenté aussi clairement que sur certains graphes.

<img alt="Tendance générale des PNG, ratio de compression en fonction de la qualité pour les différents formats d'images"
     class="big iframe-img"
     loading="lazy"
     src="res/iframe_imgs/Tendance générale des PNG.png">


On remarque cependant que la légère dominance de AVIF sur HEIF est claire dans ce jeu de donnée.
Aussi, sur un nombre assez important d'images les formats AVIF et HEIF arrivent à réduire la taille de l'image en réduisant sa qualité alors que les autres algorithmes atteignent un seuil (chacun un seuil différent) qu'ils n'arrivent pas à dépasser.


Certaines images (👽) ont un graphe très particulier !

<img alt="Graphe de la qualité en fonction de la taille des différents formats pour l'image cat_donus_pixel_art"
     class="big iframe-img"
     loading="lazy"
     src="res/iframe_imgs/cat_donus_pixel_art_pngwing.png">


C'est le cas de `cat_donus_pixel_art` où JPEG XL est très bon en qualité 100 (sans perte) mais fait un peu moins bien que WebP sinon. WebP donne également de très bon résultat alors que WebP2 optimise difficilement la taille de l'image. AVIF donne de très mauvais résultats alors que HEIF augmente systématiquement la taille de l'image (sauf en qualité 0).

Aussi sur de grandes images très détaillées, JPEG XL peu devenir intéressant.
C'est le cas par exemple sur l'image de la capture d'écran de la page d'accueil de <https://wikipédia.org> où JPEG XL devient aussi intéressant que WebP2, lui-même meilleur que AVIF.
JPEG XL est plus performant sur de grosses images (en dimension) comme `eiffel_tower_pngwing`, `screenshot_firefox_c_quirks_fr_ache_one`.

<img alt="Graphe de la qualité en fonction de la taille des différents formats pour un Screenshot de Wikipédia"
     class="big iframe-img"
     loading="lazy"
     src="res/iframe_imgs/screenshot_firefox_wikipedia.png">


#### Photos personnelles de vacances

La tendance est très claire dans ce jeu de données.
Tous les formats excepté WebP sont excellents.

<img alt="Tendance générale des photos personnelles, ratio de compression en fonction de la qualité pour les différents formats d'images"
     class="big iframe-img"
     loading="lazy"
     src="res/iframe_imgs/Tendance générale des photos personnelles.png">


On notera les performances médiocres de WebP2 lorsque la qualité est de 100%.
Quasiment ✕ 6 sur l'image `nantes_église` et quasiment ✕ 5 sur `sleeping_bridge_beauty`.
AVIF souffre du même problème sur la qualité 100 et 90 mais pas dans de telle proportion.
JPEG XL ne rencontre **jamais** ce problème.


#### Photos de haute définition

La tendance est identifiable.
Tous les formats excepté WebP sont excellents.
On peut même classer les formats JPEG XL premier, AVIF/HEIF deuxième puis WebP2 troisième.
Il faut noter que ce classement n'est vrai pas vrai pour toutes les images.
Aussi, les trois formats ont de très bons résultats, si bien que la différence entre WebP2 et JPEG XL n'est pas si notable que ça.

<img alt="Tendance générale des photos de haute résolution, ratio de compression en fonction de la qualité pour les différents formats d'images"
     class="big iframe-img"
     loading="lazy"
     src="res/iframe_imgs/Tendance générale des photos de haute résolution.png">


Globalement la même tendance que le jeu de données de photo personnelles de vacances.
Les performances atteintes sont en moyennes plus grande cependant.

Aucune image ne sort du lot, excepté les performances de WebP2 en qualité 100% et effort 0.
Une taille initiale multipliée par 8.5 !


#### Photos du jeu de données de l'INRIA

Même analyse que les deux jeux de données précédents.

<img alt="Tendance générale des photos du jeu de données de l'INRIA, ratio de compression en fonction de la qualité pour les différents formats d'images"
     class="big iframe-img"
     loading="lazy"
     src="res/iframe_imgs/Tendance générale des photos du jeu de données de l'INRIA.png">


#### Images PNG issues de XKCD

Très mauvais résultats pour JPEG XL globalement pire que WebP, sauf sur une image, où il excelle en mode sans perte. (`1416.jpg`).
WebP2 s'en sort bien.
AVIF/HEIF également, tout à fait équivalent.
On rencontre deux tendances.

<img alt="Tendance générale des PNG issues de XKCD, ratio de compression en fonction de la qualité pour les différents formats d'images"
     class="big iframe-img"
     loading="lazy"
     src="res/iframe_imgs/Tendance générale des images PNG issues de XKCD.png">

La première, la plus courante, une domination de WebP2 et AVIF/HEIF (équivalent) sur les autres formats.
On note par contre que WebP2 est plus performant sur certaines images (136, 209, 399, 695, 731, 1071).
Le point commun de ces images est qu'elles ont des couleurs, souvent beaucoup de couleurs.
Mais il y a des images en couleur où le gain de performance n'est pas significatif.

La deuxième, que l'on rencontre sur les images 1123, 1144 et dans une moindre mesure 376, 1163, 1195 et 1445 est que JXL est meilleur que les autres lorsque la qualité est bonne et WebP est meilleur que les autres lorsque la qualité est faible.
Cette tendance était difficilement prévisible.
Le point commun de ces images est leur faible dimension.


<img alt="Tendance des PNG de XKCD où WebP et JXL dominent alternativement les autres formats, ratio de compression en fonction de la qualité pour les différents formats d'images"
     class="big iframe-img"
     loading="lazy"
     src="res/iframe_imgs/Tendance des images PNG de XKCD où JXL et WebP dominent les autres formats.png">

Une exception est l'image 1416, celle qui a fait bugger l'encodeur `heic-enc`.
 - Elle a été très dur à compresser pour les différents encodeurs.
 - WebP n'a pas une seule image plus petite que l'originale.
 - JXL a besoin d'avoir une qualité de 100 pour produire des images plus petites que l'image originale.
 - WebP2 a de très bon résultat en qualité 100, sinon il n'arrive pas à grand-chose même si parfois il arrive à faire plus léger que l'image originale.


### Vitesse globale des encodeurs

À qualité égale, les encodeurs prennent des temps très différents.
Ici, en prenant comme base les points du format AVIF et en comparant aux points de similarité et ratio similaire, on obtient ce graphique:

:::attention
L'échelle est logarithmique afin d'afficher toutes les données sur le graphique.
:::

<img alt="Temps d'encodage des encodeurs."
     class="big iframe-img"
     loading="lazy"
     src="res/iframe_imgs/Temps d'encodage par encodeur.png">

On voit ainsi que WebP est le format globalement le plus rapide.
Suivent ensuite AVIF et HEIF mais JPEG XL est très proche. Il est même en moyenne plus rapide.
L'anomalie ici est WebP2 qui est globalement beaucoup plus lent (notez que l'échelle est logarithmique ...)

AVIF et HEIF sont les plus constants, ce sont les seuls encodeurs à encoder toutes les images en moins de 10s.
JPEG XL a mis jusqu'à 2min pour encoder certaines images alors WebP2 a mis parfois 2h à encoder une image !


### Étude des temps de décodage

J'ai étudié le temps de décodage des différents formats, mais **ils sont tous à peu près identiques**.
Toutes les images sont décodées en 10s maximum par touts les formats d'images.

:::note
Ce résultat est assez surprenant.
Il ne serait pas étonnant qu'une erreur se soit glissée dans ces mesures et que par exemple ce soit le temps d'écriture sur le disque qui soit mesuré ici.

Le plus propable est que le temps d'encodage PNG soit d'un ordre plus grand que le décodage des différents formats.
:::

Une légère tendance pour JPEG XL à être plus lent qu'AVIF et WebP2 à être plus rapide qu'AVIF.

<img alt="Temps médian de décodage des encodeurs."
     class="big iframe-img"
     loading="lazy"
     src="res/iframe_imgs/Temps médian de décodage par décodeur.png">

<img alt="Temps moyen de décodage des décodeurs."
     class="big iframe-img"
     loading="lazy"
     src="res/iframe_imgs/Temps moyen de décodage par décodeur.png">


:::information
Ici, je n'ai pas activé le décodage progressif de JPEG XL.
Il aurait été intéressant de voir si le décodage progressif de JPEG XL aurait permis un affichage plus rapide.
:::


### Rétrospective sur cette étude

Je pense que cette étude peut être améliorée.
Je compte refaire en juillet 2024 cette comparaison et j'aimerais lister les points d'amélioration.

1. Améliorer la reproductibilité avec une image Docker.

2. Faire une comparaison à BPP égal (temps / qualité) et à qualité égale (BPP et temps).
   C'est particulièrement compliqué mais c'est faisable.

3. Étudier plus d'encodeurs.
   Ici, j'ai fait l'amalgame encodeur ≈ format, mais il est vrai que la qualité de l'encodeur joue un rôle particulier dans la représentation d'un format.

4. Utiliser plusieurs métriques de qualité d'image.

5. Inclure le format [BPG (Better Portable Graphic)](https://bellard.org/bpg/) pour comparaison.

1. J'ai voulu comparer uniquement des encodages d'images avec perte. Sauf que JPEG XL en qualité 100 est automatiquement un format sans perte. ❌
   La prochaine fois, j'aimerais inclure les versions sans perte des différents encodeurs.

6. Vérifier la validité des temps de décodage.


Conclusion
----------

Notez que dans tous les cas AVIF, WebP2 et JPEG XL sont généralement plus intéressants que JPEG ou PNG.

En prenant en compte le support actuel des navigateurs (aout 2023).
N'utilisez AVIF que si Edge (ou QQ Browser) n'est pas essentiel pour vous.
Si vous pouvez, utilisez la balise [picture](https://developer.mozilla.org/fr/docs/Web/HTML/Element/picture) pour vous préparer aux futurs formats d'images.
Vous pourrez ainsi dès aujourd'hui proposer AVIF à ceux qui le supportent, sinon utilisez WebP[^png].

[^png]: Ou PNG si vous devez supporter de très vieux navigateurs.

En prenant en compte uniquement les qualités et défauts des différents encodeurs, par exemple dans une optique de stockage, ou dans un futur où ces formats sont supportés par le navigateur.

**JPEG XL** devrait être utilisé pour toutes les **photographies**.
Pour les PNG, il est difficile de choisir entre AVIF et WebP2 dans le cas général, choisissez WebP2 avec un effort de 6 et une qualité de 90 ou AVIF une qualité entre 80 et 90.
Si vous traitez vos images manuellement, testez AVIF et WebP2, voyez celui qui colle le mieux à vos données.
Si vous effectuez un **traitement automatique**, utilisez de préférence **WebP2**, mais gardez en tête que AVIF est un très bon candidat également, notamment si vous êtes contrains en temps d'encodage ou charge CPU ou que vous avez des images de dimensions arbitrairement grandes.

Ainsi, ce que j'observe entre en contradiction avec d'autres études sur le sujet. [^autres]
Cela peut être dû aux avancés depuis des encodeurs.
En effet, libjxl et libheif sont en développement actif alors que [libwp2](https://chromium.googlesource.com/codecs/libwebp2/) est en pause.
Malgré la maturité de l'encodeur, il semble que [WebP2 ne dépassera pas le stade expérimental](https://chromium.googlesource.com/codecs/libwebp2/+/1251ca748c17278961c0d0059b744595b35a4943%5E%21/).


[^autres]: Comme cette étude de [Mozilla de 2013](https://web.archive.org/web/20160524224706/https://people.mozilla.org/~josh/lossy_compressed_image_study_october_2013/) ou celle de [Google de 2011](https://web.archive.org/web/20220429073742/https://developers.google.com/speed/webp/docs/webp_study) (mais mise à jour plusieurs fois).

:::details
Ressources complémentaires

 - Le [fichier torrent](res/datasets_test_imgs_ache.torrent) ([lien magnet 🧲](magnet:?xt=urn:btih:3217ff465d9c13cdbb2f7b1d776ee0f2a152ba54&dn=datasets_test_imgs_ache&tr=udp://tracker.opentrackr.org:1337/announce&tr=https://tracker1.520.jp/announce&tr=udp://tracker.torrent.eu.org:451/announce&tr=http://bt.endpot.com/announce)).
 - Les [données brutes](res/raw_data_images_format_2023.csv).

:::

<script src="https://ache.one/s/js/plotly.min.js" charset="utf-8" async></script>