Dynamic Alpha

Ces temps ci, c’est la mode des slides, coverflows et autres éléments de navigation ou publicité qui nécéssitent un défilement d’images, variées, autant sur les sujets que sur le contenu. Un client vient me voir, et me dit qu’il veut un de ces sliders deezer-like, avec des onglets, défilement d’images externes avec un loader et un petit panneau noir transparent sur lequel on appose des liens écrits en blanc.

Arrivé au moment du final, on pose les vraies images, et on constate un truc évident.

Dans le cas d’une image lumineuse, soit le panneau est trop opaque, cache inutilement les images avec son alpha proche de 1, et on perds la “spatialité” de cette merveilleuse grande image ; soit le panneau n’est pas assez opaque et vu que la typo est blanche, on lit plus rien du tout (notons que ca aurait été l’effet inverse avec une typo noire) ; un peu comme l’illusion d’optique des niveaux de gris

Il m’est venu alors l’idée (peut etre un peu inutile) de pouvoir changer l’alpha de ce petit panneau noir, dynamiquement, en fonction des images que j’avais d’affichées a l’écran.

Voici un premier test qui montre 2 blocs de texte avec un alpha statique, et 1 avec un alpha dynamique. Vous pouvez drag’n'dropper les blocs de texte pour faire des comparaisons.

Sur une madame trouvée sur gougueule (plus sympa a regarder que Bernard Maitenaz, inventeur des verres progressifs), on voit bien que sur les parties claires, autant que sur les parties sombres, l’alpha dynamique permet au texte de rester lisible sans trop masquer l’image qui est derriere.

La technique que j’utilise est de capturer la zone de pixel se trouvant en dessous de mon objet devant être lisible. Je la parcours, en additionnant la valeur de luminosité de chaque pixel, afin de déterminer assez basiquement une luminosité moyenne.

J’utilise la classe Label de martian.milky.labels pour afficher les blocs de texte (objet “someText”).

var ba:ByteArray = image.bitmapData.getPixels(new Rectangle(someText.x, someText.y, someText.width, someText.height));
ba.position = 0;

var total:uint, color:Array;

while (ba.position < ba.length)
{
color = int2rgb(ba.readUnsignedInt() - 0xff000000);
total += color[0] < color[1] ? color[1] < color[2] ? color[2] : color[1] : color[0];
}
var average:Number = (total / luminosity.position) / 100;

var ratio:Number = total / (0xff * luminosity.position);

someText.refresh( { str:"dynamic alpha (" + average.toFixed(2) + ")", ss:new ShapeStyle( { fillAlpha:average } ) } )


UPDATE !

Cet article date un peu, et maintenant le client pour lequel j’avais réfléchi à ça a mis en ligne son site (qui vaut ce qu’il vaut :p) : http://vitrine.commercequitable.org/front/

Le module flash est nourri par un xml, ce qui permet aux admins de changer les images facilement (entre autres). Cet algo est appliqué au premier passage de chaque image et les valeurs sont conservées dans un tableau pour minimiser les phases de calcul. Comme on peut le voir, ca marche aussi pour la couleur ;)

Comments (4)

  1. Matthieu wrote::

    En tous cas moi je trouve que c’est une bonne idée :)
    Surtout dès que l’on manipule du contenu dynamique ce genre de principe de régulation entre éléments d’interface ca me plait bien :)

    Tuesday, October 21, 2008 at 9:44 pm #
  2. Soulwire wrote::

    Great idea! I can see this being very useful for sure… Keep up the good work :)

    Sunday, November 16, 2008 at 10:02 pm #
  3. keusta wrote::

    bonne idée qui marche bien sur des valeurs de gris, mais qu’en est il sur de la couleur ?

    Thursday, April 23, 2009 at 5:20 pm #
  4. admin wrote::

    L’algo marche également !
    En fait, pour trouver l’alpha moyen, il faut d’abord trouver la luminosité moyenne qui se trouve en dessous ! Qui dit luminosité dit HSL plutot que RGB. Les algos de conversion HSL-> RGB que j’ai pu cotoyer extrayaient la luminosité en prenant la valeur la plus forte des trois composantes RGB, ce qui est fait en ligne 9 !

    Friday, April 24, 2009 at 9:51 am #