Aller au menu - Aller au contenu

Icône Les PNG 24 Bits

Mise à jour : 12/05/2009
1 640 visites depuis 7 jours , dont 74 sur ce chapitre , classé 85/777
Parlons un peu, mais bien, des images au format PNG 24 Bits. Comme vous le savez, IE rencontre quelques problèmes (2 seulement ^^ ) avec ce format graphique. Apportons-y une solution ;)

Pour ne pas tout le temps dire PNG 24 Bits, je dirai juste PNG ;) .
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

AlphaImageLoader

AlphaImageLoader est un filtre CSS développé par Microsoft. La principale utilisation de ce filtre est de permettre d'obtenir un affichage correct des zones transparentes que peuvent comporter les images PNG, sous Internet Explorer 6. En effet, IE6 affiche les zones transparentes en gris clair, ce qui est assez embêtant et peut faire tache au sein de votre design.

Je vais donc vous expliquer comment fonctionne AlphaImageLoader ; il existe deux techniques plus ou moins distinctes pour l'utiliser, mais avant, un petit point de théorie sur ce filtre s'impose.

Structure



AlphaImageLoader s'applique au moyen de la propriété CSS filter, comme ceci :

Code : CSS
1
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='image.png');


La seule chose à modifier est l'attribut src, qui représente l'url de votre image .png.

Utilisation avec l'élément IMG



Imaginons que votre image soit insérée au moyen de l'élément IMG. Il va falloir passer par l'élément IMG pour les navigateurs autres qu'IE, et un élément DIV sur lequel on appliquera le filtre, dans le cas d'Internet Explorer. Pour faire la différence entre les types de navigateurs je vais utiliser des instructions conditionnelles.

Code : HTML
1
2
3
4
5
<!--[if IE 6]><div style="position: relative; style="height:130px; width:160px; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='data/rectangle.png');" ></div><![endif]-->

<!--[if !IE]><-->
<img src="data/rectangle.png" alt="Rectangle" />
<!--><![endif]-->


J'applique donc l'AlphaImageLoader sur un élément DIV. Il est très important de spécifier une position relative ainsi que la hauteur et la largeur de l'image, sinon l'image ne sera pas correctement affichée (elle risque d'être étirée).

Utilisation en arrière-plan



Il peut être intéressant de créer son design avec des images d'arrière-plan, notamment pour faire des menus. Si votre image d'arrière-plan est au format PNG, il faut utiliser l' AlphaImageLoader directement dans les CSS (élément STYLE ou feuille de style externe).
Là encore, il vaut mieux utiliser des instructions conditionnelles, car il va se poser un problème au niveau de la propriété background.

Pour mettre une image d'arrière-plan, on utilise donc la propriété background (ou background-image, au choix), seulement, le filtre ne remplace pas l'arrière-plan, et cet arrière-plan s'affichera sous IE6 malgré l'AlphaImageLoader, comme le démontre le code suivant :

Code : CSS
1
2
3
4
5
6
7
#div {
        background: url(data/rectangle.png) no-repeat;
        filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='data/rectangle.png');
        height: 130px; 
        width: 260px;
        margin: auto;
}


Pour régler ce léger problème, il suffit d'appliquer un background: none ; pour Internet Explorer, et c'est pour ça qu'on va utiliser des instructions conditionnelles, de manière à obtenir un code propre et valide, car la propriété filter n'est pas valide.

Pour la simplicité de compréhension, je vais utiliser les éléments STYLE pour définir les styles CSS. Libre à vous d'utiliser des feuilles de style.


On commence par les styles généraux :

Code : CSS
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<style type="text/css">
<!--
#div {
        background: url(data/rectangle.png) no-repeat;
        height: 130px; 
        width: 260px;
        margin: auto;
}
//-->
</style>


Et ensuite, dans une instruction conditionnelle, on définit les CSS qu'Internet Explorer 6 interprétera :

Code : CSS
1
2
3
4
5
6
<!--[if IE 6]><style type="text/css">
#div {
        filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='data/rectangle.png');
        background: none;
}
</style><![endif]-->


Mais il subsiste un problème plutôt étrange ! Si vous avez essayé de mettre un lien hypertexte au sein de l'élément auquel l'arrière-plan est appliqué (#div, dans mon exemple), ce lien n'est plus cliquable sous Internet Explorer (le même problème survient avec les champs de texte et les éléments qui régissent à hover). Une solution toute simple pour régler ce bug est de placer le lien, ou les liens, en position relative, comme le montre l'exemple ci-dessous :

Code : CSS
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<style type="text/css">
<!--
#div {
        background: url(data/rectangle.png) no-repeat;
        height: 130px; 
        width: 260px;
        margin: auto;
}
#div a {
        position: relative; 
        top: 10px;
        left: 20px;
}
//-->
</style>
<!--[if IE 6]><style type="text/css">
#div {
        filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='data/rectangle.png');
        background: none;
}
</style><![endif]-->


Voci le code HTML qui va avec le CSS :

Code : HTML
1
<div id="div"><a href="http://nayi.free.fr/">Lien hypertexte</a></div>

Le patch Javascript

Cela n'est une surprise pour personne, IE ne gère pas la transparence des images PNG. Comme avec les hovers, on sait se dépêtrer de ce léger problème :)

Voici le code à placer dans le HEAD de votre page :

Code : HTML
1
2
3
<!--[if lt IE 7.]>
<script type="text/javascript" src="sleight.js"></script>
<![endif]-->


Vous avez vu les instructions conditionnelles, donc vous pouvez comprendre ce code.

Dans un fichier nommé sleight.js, copiez-collez ce code :

Code : JavaScript
 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
/**********************************************************
Sleight Simple
  (c) 2001, Aaron Boodman
  <lien url="http://www.youngpup.net">http://www.youngpup.net</lien>

Sleight Background
  (c) 2001, Aaron Boodman
  (c) 2003, Drew McLellan
  <lien url="http://www.allinthehead.com">http://www.allinthehead.com</lien>
**********************************************************/
if (navigator.platform == "Win32" && navigator.appName == "Microsoft Internet Explorer" && window.attachEvent) {
        window.attachEvent("onload", alphaBackgrounds);
        
        document.writeln('<style type="text/css">img { visibility:hidden; } </style>');
        window.attachEvent("onload", fnLoadPngs);
}
// Sleight Background
function alphaBackgrounds(){
        var rslt = navigator.appVersion.match(/MSIE (\d+\.\d+)/, '');
        var itsAllGood = (rslt != null && Number(rslt[1]) >= 5.5);
        for (i=0; i<document.all.length; i++){
                var bg = document.all[i].currentStyle.backgroundImage;
                if (itsAllGood && bg){
                        if (bg.match(/\.png/i) != null){
                                var mypng = bg.substring(5,bg.length-2);
                                document.all[i].style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+mypng+"', sizingMethod='scale')";
                                document.all[i].style.backgroundImage = "url('/assets/images/x.gif')";
                        }
                }
        }
}
// Sleight Simple
function fnLoadPngs()
{
        var rslt = navigator.appVersion.match(/MSIE (\d+\.\d+)/, '');
        var itsAllGood = (rslt != null && Number(rslt[1]) >= 5.5);

        for (var i = document.images.length - 1, img = null; (img = document.images[i]); i--)
        {
                if (itsAllGood && img.src.match(/\.png$/i) != null)
                {
                        var src = img.src;
                        var div = document.createElement("DIV");
                        div.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', sizing='scale')"
                        div.style.width = img.width + "px";
                        div.style.height = img.height + "px";
                        img.replaceNode(div);
                }
                img.style.visibility = "visible";
        }
}


Je ne vais pas vous expliquer ce code. Ce que je peux vous dire, c'est qu'il utilise le AlphaImageLoader Filter de Microsoft pour attribuer une transparence aux fichiers PNG.

Note de mise à jour :

Dans un premier temps, je vous parlais du script pngfix (http://homepage.ntlworld.com/bobosola/index.htm). Mais il comportait un problème : il ne permettait pas de gérer la transparence des PNG affichées en arrière-plan.

PngOptimizer

Image utilisateur
Nous n'avons pas fini de parler des PNG :D . En effet, Internet Explorer assombrit légèrement, vraiment très légèrement, les images PNG. Regardez cette image : à gauche, une image PNG avec Firefox, et à droite, la même image, mais avec IE (ce sont des captures d'écran) :

Image utilisateur


Vous constatez par vous-même que j'ai raison, il y a bien une différence. Ce n'est pas un problème important. Si vous faites un bête logo, et qu'il est légèrement assombri, en fait, personne ne le remarquera ;)

Mais, si par exemple vous avez un logo avec un fond définit, qui est sensé se mettre dans un bloc avec un arrière-plan (définit par une couleur en CSS) qui est le même que celui du logo, il y aura une différence bien visible, comme le prouve le test ci-dessous.

Dans un div, avec comme couleur d'arrière-plan du #DBDBE9, j'ai placé, au centre, une image PNG carrée de 50*50 pixels, de couleur #DBDBE9. Regardez la différence entre IE et Firefox :

Image utilisateur Image utilisateur


Pour résoudre ce problème, il vous faut utiliser le programme PngOptimizer, gratuit.



Une fois téléchargée, ouvrez PngOptimizer.exe. L'utilisation de ce mini-soft est un jeu d'enfant de zéro. Il vous suffit de prendre une image dans votre explorateur, et de la déplacer (drag and drop) dans l'interface, comme indiqué sur ce screen :

Image utilisateur


Le fichier .png est alors « optimisé », et son affichage se fait sans problèmes avec IE :

Image utilisateur
Chapitre précédent Sommaire Chapitre suivant

Partager

21 commentaires pour "Les PNG 24 Bits"
Note moyenne : 3.56 / 4 (25 votes)
Pseudo Commentaire
Hors ligne Ishimaru Chiaki # Posté le 13/08/2009 à 03:42:48
Kernel panic !
Flux RSS

Ville : Baie-comeau
Pays : Canada

Je reviens sur le tutoriel pour donner les résultats d'une nouvelle expérimentation que j'ai faite suite à la réapparition récente du problème avec des PNG24 utilisant une fausse transparence.

Il se trouve que le problème survient lorsqu'on enregistre le gamma au moment d'enregistrer l'image au format PNG

Vous pouvez visualiser avec IE le résultat de mon expérimentation sur cette page de test, où j'ai testé avec PNG24, PNG8, avec ou sans canal alpha, avec ou sans gamma, et dans tous les cas, avec une fausse transparence : http://youwontfindme.editboard.com/Tes [...] lorer-h33.htm

EDIT : Suite à d'autres tests, il se trouve qu'il faut vérifier aussi au niveau de l'hébergeur d'image utilisé, car certains hébergeurs, comme Photobucket, appliquent un traitement gamma aux images lors de l'upload, ce qui fait toujours assombrir les PNG sous IE.

Donc, au final, les deux causes possibles de l'assombrissement, toutes deux liées au gamma :
- Enregistrement du gamma lors de l'export en PNG
- Traitement gamma lors de l'upload d'une image PNG sur un hébergeur d'image.

Présentement en mode « Codage de mon site »
 
Hors ligne anonyme # Posté le 19/08/2009 à 12:13:00

Excellent tutoriel, mais j'ai quand même un problème : mes images en background sont complètement déformées (quand elles s'affichent), j'ai fait une capture d'écran pour vous montrer :
Image utilisateur
Ça devrait juste être des petites images de 16 x 16 pixels...
Hors ligne Ishimaru Chiaki # Posté le 23/08/2009 à 10:34:27
Kernel panic !
Flux RSS

Ville : Baie-comeau
Pays : Canada

En effet, j'ai eu ce même problème avec sleight (et aussi iepngfix) en plus que ça mettait tous mes éléments <img /> en block.

Comme script de remplacement, je te conseille celui qui est indiqué dans ce tuto que j'ai rédigé sur phpbb-fr : http://forums.phpbb-fr.com/tutoriaux-p [...] et155267.html

Le script a été testé sur le thème Pro_vistablue de Samurai et mon thème Pro_ubuntu, tous deux pour phpBB3, avec succès.
Il marche à la fois pour les fonds et les <img />.

Présentement en mode « Codage de mon site »
 
Hors ligne ccyborg # Posté le 18/09/2009 à 13:06:02

il y a aussi le script pngbehavior.htc que l'on peut trouver ici :
http://webfx.eae.net/download/pngbehavior102.zip

Chez moi il ne marchait pas pour ie6 voici le fichier corrigé... si ça interesse :

Citation

<public:component lightWeight="true">
<public:attach event="onpropertychange" onevent="propertyChanged()" />
<public:attach event="onbeforeprint" onevent="beforePrint()" for="window"/>
<public:attach event="onafterprint" onevent="afterPrint()" for="window"/>
<script>

/*
* PNG Behavior
*
* This script was created by Erik Arvidsson (http://webfx.eae.net/contact.html#erik)
* for WebFX (http://webfx.eae.net)
* Copyright 2002-2004
*
* For usage see license at http://webfx.eae.net/license.html
*
* Version: 1.02
* Created: 2001-??-?? First working version
* Updated: 2002-03-28 Fixed issue when starting with a non png image and
* switching between non png images
* 2003-01-06 Fixed RegExp to correctly work with IE 5.0x
* 2004-05-09 When printing revert to original
* 2009-09-18 Fixed ie6 image disappearing
*
*/

var supported = /MSIE ((5\.5)|[6789])/.test(navigator.userAgent) &&
navigator.platform == "Win32";

var realSrc = "";
var blankSrc = "/clear.gif";
var isPrinting = false;
if (supported) fixImage();

function propertyChanged() {
if (!supported || isPrinting) return;

var pName = event.propertyName;
if (pName != "src") return;
// if not set to blank
if (!new RegExp(blankSrc).test(src))
fixImage();
};

function fixImage() {
// get src
var src = element.src;
// get native image size
var w = element.width;
var h = element.height;

// check for real change
if (src == realSrc && /\.png$/i.test(src)) {
element.src = blankSrc;
return;
}

if ( ! new RegExp(blankSrc).test(src)) {
// backup old src
realSrc = src;
}

// test for png
if (/\.png$/i.test(realSrc)) {
// set blank image
element.src = blankSrc;
// set filter
element.runtimeStyle.filter = "progid:DXImageTransform.Microsoft." +
"AlphaImageLoader(src='" + realSrc + "',sizingMethod='scale')";

// FIX for ie6 (v6.0.3790.3959)
if (/MSIE 6/.test(navigator.userAgent)) {
element.runtimeStyle.backgroundImage = 'url("'+blankSrc+'")';
element.runtimeStyle.backgroundPosition = '0 0';
element.runtimeStyle.width = w+'px';
element.runtimeStyle.height = h+'px';

element.runtimeStyle.filter = "progid:DXImageTransform.Microsoft." +
"AlphaImageLoader(src='" + realSrc + "',sizingMethod='scale')";
}
}
else {
// remove filter
element.runtimeStyle.filter = "";
}
}

function beforePrint() {
isPrinting = true;
element.src = realSrc;
element.runtimeStyle.filter = "";
realSrc = null;
}

function afterPrint() {
isPrinting = false;
fixImage();
}

</script>
</public:component>
Hors ligne eric z # Posté le 27/11/2009 à 14:51:40
Avatar

Ville : Clichy
Pays : France métropolitaine

Merci pour ce très utile tutoriel.
Le code donné pour l'utilisation de AlphaImageLoader avec l'élément IMG n'affiche pas d'image pour les versions IE 7 et 8.

Code : HTML
1
2
3
4
5
<!--[if IE 6]><div style="position: relative; style="height:130px; width:160px; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='data/rectangle.png');" ></div><![endif]-->

<!--[if !IE]><-->
<img src="data/rectangle.png" alt="Rectangle" />
<!--><![endif]-->

Ceci convient:
Code : HTML
1
2
3
4
5
<!--[if IE 6]><div style="position: relative; style="height:130px; width:160px; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='data/rectangle.png');" ></div><![endif]-->
<!--[if gt IE 6]><img src="data/rectangle.png" alt="Rectangle" /><![endif]-->
<!--[if !IE]><-->
<img src="data/rectangle.png" alt="Rectangle" />
<!--><![endif]-->

Voir tous les commentaires