28182 sujets

CSS et mise en forme, CSS3

J'aimerais comprendre comment est calculée une couleur d'un élément HTML lorsque la propriété opacity lui est appliquée.

Prenons cet exemple :

#div1 {
  opacity: 0.6;
  background-color: rgba( 155 , 66 , 200 , 0.5 );
  width:200px;
  height: 200px;
}

#div2 {
  background-color: rgba( 0, 77 , 100 , 0.8 );
  width: 200px;
  height: 200px;
}


<div id="div1" >
    <div id= "div2"></div>
 </div>


J'ai d'abord utilisé la formule du "simple alpha compositing"
https://www.w3.org/TR/compositing-1/#simplealphacompositing

co = Cs x as + Cb x ab x (1 - as)
ao = as + ab x (1 - as)

J'applique cette formule dans mon exemple,
Cs et as sont la couleur et l'alpha du div2,
Cb et ab sont la couleur et l'alpha du div1.

co = ( 0 , 77/255 , 100/255 ) * 0.8 + ( 155/255 , 66/255 , 200/255 ) * 0.5 * ( 1 - 0.8 )
co = ( 0.06 , 0.267 , 0.392 )
ao = 0.8 + 0.5 * ( 1 - 0.8 )
ao = 0.9

le résultat, co, est une valeur prémultipliée.
Pour trouver la couleur associée , il faut diviser co par ao. On note Co (majuscule), Co = co/ao.

Mais je vais appliquer la propriété "opacity" sur la valeur prémultipliée, co et sur l'alpha ao.

co * opacity = ( 0.06 , 0.267 , 0.392 ) * 0.6
ao * opacity = 0.9 * 0.6

co * opacity = ( 0.036 , 0.1602 , 0.2352 )
ao * opacity = 0.54

Maintenant j'extraie la couleur en divisant ( 0.036 , 0.1602 , 0.2352 ) par 0.54.
ce qui donne ( 0.036/0.54 , 0.1602/0.54 , 0.2352/0.54) = ( 0.07 , 0.27 , 0.43 ).

Cette couleur , ( 0.07 , 0.27 , 0.43 ) , je la compose avec la couleur de fond, (celle de l'élément <body> qui est blanc ( 1,1,1).

( 0.07 , 0.27 , 0.43 ) * 0.54 + ( 1 , 1 , 1 ) * 1 * ( 1 - 0.54 ) =
(0.49 , 0.6 , 0.232 )

Ce résultat correspond à la couleur obtenue :
upload/1662760721-84980-sanstitre.png

Alors voilà ma question :
La façon dont j'ai calculée la couleur obtenue je l'ai obtenue après plusieurs essais, je n'ai pas trouvé de site qui donne clairement le mode de calcul.
Notamment, pourquoi l'opacité est appliquée sur la valeur prémultipliée ?
Et où trouver les explications détaillées du calcul de couleur .

J'ai posé la question sur w3c : https://github.com/w3c/csswg-drafts/issues/7718
mais pas de réponse claire.
Le site stackoverflow est pas mal, mais la compréhension de l'anglais ajoute une dimension au problème !


Bon je m'étais complétement embrouillé...
La solution est bien plus simple :

Quand un élément contient une couleur rgba(r,g,b,a) et la propriété opacity,
la couleur résultant est donnée par la formule :
(r , g , b , a * opacity )

Modifié par letochagone (14 Sep 2022 - 22:24)
Modérateur
Bonjour,

Je n'ai pas vérifié tes calculs. Mais il me semble, en ce qui concerne le mode de calcul, qu'il y a déjà tout ce qui est nécessaire dans le lien que tu as donné https://www.w3.org/TR/compositing-1/#simplealphacompositing

En ce qui concerne la question "pourquoi l'opacité est appliquée sur la valeur pré-multipliée ?" la pré-multiplication n'est qu'un résultat intermédiaire qui permet d'éviter de tout recalculer, et éventuellement de rendre plus clair la compréhension de l'algorithme de composition (selon certains Smiley lol ).

Quelques explications supplémentaires (en français) ici https://fr.wikipedia.org/wiki/Alpha_blending

Amicalement,
Modifié par parsimonhi (13 Sep 2022 - 10:10)
Meilleure solution
parsimonhi a écrit :
Bonjour,

Je n'ai pas vérifié tes calculs. Mais il me semble, en ce qui concerne le mode de calcul, qu'il y a déjà tout ce qui est nécessaire dans le lien que tu as donné https://www.w3.org/TR/compositing-1/#simplealphacompositing

En ce qui concerne la question "pourquoi l'opacité est appliquée sur la valeur pré-multipliée ?" la pré-multiplication n'est qu'un résultat intermédiaire qui permet d'éviter de tout recalculer, et éventuellement de rendre plus clair la compréhension de l'algorithme de composition (selon certains Smiley lol ).

Quelques explications supplémentaires (en français) ici https://fr.wikipedia.org/wiki/Alpha_blending

Amicalement,


Bonjour !

D'après mes résultats l'opacité est appliquée sur la valeur prémultipliée, mais ici, la valeur prémultipliée est transformée par l'opacité. Puis elle est démultipliée.
Si elle est d'abord démultipliée puis transformée par l'opacité, la couleur résultante est différente.
Ce que j'aimerais trouver c'est où, sur quel site, savoir le détail de la propriété "opacity", afin de pourvoir la simuler, et notamment produire une fonction équivalente en WebGL.

sur le lien que j'ai donné https://www.w3.org/TR/compositing-1/#simplealphacompositing
il y a une explication précise avec des valeurs co et CO (en majuscule signifie non-prémultipliée).
Mais je ne trouve pas d'explications aussi précises sur d'autres propriétés, et notamment : opacity !

J'ai posé la question sur :
https://github.com/w3c/csswg-drafts/issues/7605
mais la réponse n'est pas précise (pour moi).

J'ai posé une autre question pour savoir où trouver les "codes sources" des propriétés CSS :
https://github.com/w3c/csswg-drafts/issues/7733
Mais pas encore trouvé de réponse en fouillant ce lien

voilà !
Modifié par letochagone (14 Sep 2022 - 14:41)
Modérateur
Bonjour,

Basiquement, quand la couleur de fond n'a pas de transparence (composante alpha du fond = 1), mais que la couleur de devant en a une, on fait (1-composante_alpha_du_devant)*couleur_du_fond + composante_alpha_du_devant*couleur_de_devant pour chacune des composantes de la couleur (c'est à dire les composantes rouge, verte et bleue) pour obtenir la couleur à afficher.

Lorsque la couleur de fond a elle aussi une transparence, le calcul devient un peu plus compliqué et c'est ce calcul qui est expliqué dans les liens https://www.w3.org/TR/compositing-1/#simplealphacompositing et https://fr.wikipedia.org/wiki/Alpha_blending

Si tu remplaces la composante alpha de la couleur du fond par 1 dans la formule générale (celle qui tient compte à la fois de la transparence de la couleur du fond et de la transparence de la couleur de devant), tu retrouves la formule basique (1-composante_alpha_du_devant)*couleur_du_fond + composante_alpha_du_devant*couleur_de_devant qui n'est qu'un cas particulier de cette formule générale.

Amicalement,