# Optimiser ses images avec le «Dithering»

Afin de diminuer au maximum le poid de ces images, le site de [LOW←TECH&nbsp;MAGAZINE] à mit en place une ancienne technique de compression d’image appelée « diffusion d’erreur ».

Cette technique repose sur deux grand principes :

## La «quantification des couleurs»

Une image habituel est composé de pixel pouvant avoir nimporte quel couleur codé sur trois canneaux : **Rouge, Vert, Bleu**, avec pour chaque une **valeur allant de 0 à 255**.

**L’indexation d’image** est une technique qui consiste à réduire les couleurs de l’image à une **palette réduite**.

Cette technique, aussi nommée «**Color Quantization**» économise beaucoup de poid, **mais laisse place à moins de nuances**.

L’équipe de [LOW←TECH&nbsp;MAGAZINE] a fait le choix d’utilier 4 nuances de gris, et d’y appliquer un filtre CSS pour remplacer le blanc par une couleur : `mix-blend-mode: hard-light;`

Par contre, si on se contente d’indexer les couleurs d’une image dans Gimp ou Photoshop, le rendu visuel ne sera pas forcément optimal, surtout en monochrome.

## Le «trammage»

Pour améliorer la visibilité de l’image avec le moins de couleurs possibles,
une bonne astuce est d’utiliser des trames «dithering».

Vu a une certaines distance, la quantité de noir et de blanc se mélangent et sont percu comme un gris.

Il existe plusieurs algorythme de dithering, [imagemagick](http://www.imagemagick.org/Usage/quantize/) permet entre autre d’en appliquer en ligne de commande.

---

# R&D de compression

J’ai voulu expérimenter différentes options d’[imagemagick](http://www.imagemagick.org/Usage/quantize/) pour comparer les résultat tant visuelment que sur le poid du fichier final.

- Je suis partis de cette [image source](https://images.unsplash.com/photo-1542672701-2ec46535709f?ixlib=rb-1.2.1&auto=format&fit=crop&w=3648&q=80).
- Le poid des images s’affichent au survol.

## Quantification des couleurs

```sh
# Resize & 2 grey : 19KB
convert gare.jpg -resize 400x600 -colors 2 -colorspace gray -normalize gare1.gif

# Resize & 3 grey : 24KB
convert gare.jpg -resize 400x600 -colors 3 -colorspace gray -normalize gare2.gif

# Resize & 3 colors : 25KB
convert gare.jpg -resize 400x600 -colors 3 -normalize gare3.gif

# Resize & 4 colors : 30KB
convert gare.jpg -resize 400x600 -colors 4 -normalize gare4.gif
```
![gare1.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/lyyJ2Y6NVIyyp4on-gare1.gif "19KB")
![gare2.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/dvJyYH1UbVBjBWcM-gare2.gif "24KB")

![gare3.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/iZ76SinUlKQgyC89-gare3.gif "25KB")
![gare4.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/4G70lSExVGaYdL55-gare4.gif "30KB")


---

## Trammage en noir et blanc

```sh
# Resize & Ordered Dither 2 : 8KB
convert gare.jpg -resize 400x600 -colorspace gray -ordered-dither o2x2 gare5.gif

# Resize & Ordered Dither 3 : 10KB
convert gare.jpg -resize 400x600 -colorspace gray -ordered-dither o3x3 gare6.gif

# Resize & Ordered Dither 4 : 11KB
convert gare.jpg -resize 400x600 -colorspace gray -ordered-dither o4x4 gare7.gif

# Resize & Ordered Dither 8 : 12KB
convert gare.jpg -resize 400x600 -colorspace gray -ordered-dither o8x8 gare8.gif
```

![gare5.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/blU28pg4uTHIA9Nk-gare5.gif "30KB")
![gare6.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/aYvHBuKoBq1USqmJ-gare6.gif "10KB")

![gare7.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/tYn47ZZBz7XLsUyT-gare7.gif "11KB")
![gare8.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/5hxvUr9WXcQdgCgC-gare8.gif "12KB")

---

## Trammage en couleurs

```sh
# Resize & Ordered Dither 2 : 20KB
convert gare.jpg -resize 400x600 -ordered-dither o2x2 gare9.gif

# Resize & Ordered Dither 3 : 23KB
convert gare.jpg -resize 400x600 -ordered-dither o3x3 gare10.gif

# Resize & Ordered Dither 4 : 25KB
convert gare.jpg -resize 400x600 -ordered-dither o4x4 gare11.gif

# Resize & Ordered Dither 8 : 27KB
convert gare.jpg -resize 400x600 -ordered-dither o8x8 gare12.gif
```

![gare9.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/nLoOaRJb1mHYwHN4-gare9.gif "20KB")
![gare10.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/3Mr4g2iwQFTWhPrF-gare10.gif "23KB")

![gare11.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/P160SV9BsuWUP6mc-gare11.gif "25KB")
![gare12.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/lnjrRQ7mOr5Sp8x7-gare12.gif "27KB")

---

# Comparaison
Les [trammages en noir et blanc](#trammage-en-noir-et-blanc) donnent les meilleur compression :
- Ordered Dither 2 : `8KB` Pas assez de détails
- Ordered Dither 3 : `10KB` Beaucoup mieux
- Ordered Dither 4 : `11KB` Très bon comprimit
- Ordered Dither 8 : `12KB` Les trames commencent à être trop visible

Suivi par :
- La quantification en 2 couleurs : `19KB` pas du tout détaillée.
- Le trammage coloré Ordered Dither 2 : `20KB` même niveau de détail.

Les autres vont de `23KB` à `30KB` ce qui commence à faire beaucoup comparé au `10KB` totalement correcte que l’on a eu précédement.

**Le meilleur compromit** taille et esthétique se place donc entre :
- Ordered Dither 3 `10KB` qui fait des trames en forme de taches
- Ordered Dither 4 `11KB` qui fait des trames en forme de croix

Je vais décliner ces réglages avec différentes images sources pour avoir un avis plus avisé.

Sources :
[gare.jpg](https://images.unsplash.com/photo-1542672701-2ec46535709f?ixlib=rb-1.2.1&auto=format&fit=crop&w=3648&q=80) ;
[matcha.jpg](https://images.unsplash.com/photo-1582793863191-debca6278c90?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3241&q=80) ;
[bike.jpg](https://images.unsplash.com/photo-1558981852-426c6c22a060?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3902&q=80) ;
[desktop.jpg](https://images.unsplash.com/photo-1496917756835-20cb06e75b4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3966&q=80) ;

## Déclinaison


![gare6.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/aYvHBuKoBq1USqmJ-gare6.gif "10KB")
![gare7.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/tYn47ZZBz7XLsUyT-gare7.gif "11KB")

`10KB` & `11KB`


![matcha3.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/uIu0K4sCT86QzrwV-matcha3.gif "4KB")
![matcha4.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/sng6oudBpSMBKEoJ-matcha4.gif "4KB")

`4KB` & `4KB`


![bike3.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/zgU4rZR89UJGDRWD-bike3.gif "13KB")
![bike4.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/y4SGD2OfIfN8AwR9-bike4.gif "16KB")

`13KB` & `16KB`


![desktop3.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/90s9UF8sio9PUcEu-desktop3.gif "10KB")
![desktop4.gif](https://wiki.kher.nl/uploads/images/gallery/2020-05/DRs5wHjKPvRxiD0s-desktop4.gif "11KB")

`10KB` & `11KB`

# Conclusion
On constate que dans certains cas, le «Ordered Dither 3» manque de détail.
**Je préconise donc «Ordered Dither 4»** :

```sh
convert input.jpg -resize 400x600 -colorspace gray -ordered-dither o4x4 output.gif
```