Optimisation des images, comprendre la « dirty transparency »

Les consignes webperf un peu partout vous recommanderont de réduire la taille de vos images. Pour cela, il suffit d’utiliser des logiciels appropriés afin de supprimer toutes les méta-données qui pourrait alourdir le composant graphique.

Lorsque l’on travaille sur une image de type PNG-24, avec de la semi-transparence, on se retrouve confronté à un gros surplus d’informations causés par la transparence, appelé « dirty transparency » par les anglophones.

Avant d’expliquer ce dont il s’agit, il faut revoir la structure du format PNG :
Le PNG-24 est composé de trois informations de couleur : Rouge-Vert-Bleu, avec chacune de ces informations codé sur… 24/3 = 8 bits, soit 256 (28) teintes différentes.
En fait, le fonctionnement est identique aux couleurs hexadécimales que l’on utilise en CSS par exemple, mais répété pour chaque point.

Premier point : R-255, V-255, B-255
Deuxième point : R-253, V-254, B-255
Troisième point : R-251, V-253, B-255
etc.

Une fois l’image traitée dans sa totalité, le PNG est compressé afin d’obtenir une image de plus petite taille.

Jusque là, la seule optimisation possible de la taille de l’image résulte de l’utilisation de différentes options pour que la compression des données brutes soit optimale.

Lorsque l’on induit la transparence, On ajoute en une information de plus : le niveau de transparence, sur 8 bits soit 256 (28) niveaux de transparence.

Premier point : R-255, V-255, B-255, A-30
Deuxième point : R-253, V-254, B-255, A-0
Troisième point : R-251, V-253, B-255, A-0
etc.

Quelle est la différence ? Seulement le canal « Alpha » qui donne l’information du niveau de transparence pour le pixel.
L’image continue d’exister avec toutes les informations de couleur, même si le pixel est déclaré « totalement transparent », et, si toutes ces informations sont différentes comme dans l’exemple montré ci-dessous, la compression ne sera jamais optimale.

Heureusement, ce problème du format PNG est facile à contourner : Il suffit de remplacer tout les pixels transparents (Soit alpha = 0) par une même couleur, totalement transparente :

Premier point : R-255, V-255, B-255, A-30
Deuxième point : R-0, V-0, B-0, A-0
Troisième point : R-0, V-0, B-0, A-0
etc.

Ainsi, la compression de l’image sera bien meilleure, car le pattern le pattern « pixel transparent » est le même dans toute l’image. J’ai personnellement réussi à diviser la taille de l’image jusqu’à 3.

Pour arriver à ceci, j’utilise le code php suivant, que je vous recommande d’utiliser une seule fois, à la mise en production par exemple, puisqu’il est assez coûteux en ressources :

<?php

$i = '/path/to/png/file';
$o = '/path/to/output/file';

$in = imagecreatefrompng($i);

imagealphablending($in, false);
imagesavealpha($in, true);

$x = imagesx($in);
$y = imagesy($in);

$mx = 0;
while ($mx < $x) {
    $my = 0;
    while ($my < $y) {
        $c = imagecolorat($in, $mx, $my);
        if (($c & 0x7F000000) == 0x7F000000) {
            imagesetpixel($in, $mx, $my, 0x7F000000);
        }
        $my++;
    }
    $mx++;
}

imagepng($in, $o, 9);

Une fois le script passé, vous pouvez/devez aussi passer l’image dans votre compresseur classique afin de gagner encore quelques octets sur la taille de vos images.

Publicités

Quick Tip – Les « includes » et les « require » de PHP

Avez-vous déjà utilisé les includes et les require de PHP ?

Si oui, vous êtes peut-être déjà tombés sur le problème suivant : lorsque l’on utilise un include, le caractère « null » coupe l’inclusion du fichier.

Avez-vous déjà utilisé les includes et les require de PHP ?

Si oui, vous êtes peut-être déjà tombés sur le problème suivant : lorsque l’on utilise un include, le caractère « null » coupe l’inclusion du fichier.

Le problème est principalement posé lors de l’inclusion dynamique d’un fichier. Imaginez un simple sur le site example.com :


Il suffit d’utiliser l’URL http://example.com/?file=.htaccess%00 pour accéder au contenu du fichier .htaccess, et éventuellement bien pire !

Pour résoudre le problème ? Vérifier que le fichier inclus est bien un fichier que l’on autorise à l’inclusion, avec éventuellement un tableau des fichiers autorisés, tester que le fichier est bien un fichier PHP (et donc que le contenu sera interprété), et toute autre vérification, qui bien entendu ne sera pas superflue.

Mais évidement, vous faites déjà les vérifications nécessaires 😉