J'écris un sélecteur de couleurs qui obtient les valeurs RVB en pixels de l'endroit où vous pointez sur l'écran. Je veux également avoir la possibilité de spécifier que la couleur que j'ai choisie a déjà une valeur alpha. Je me demande simplement comment calculer la couleur résultante.
Par exemple:
La couleur résultante des pixels est 240,247,249 mais je sais que la couleur d'origine avait une opacité de 10% et était au-dessus d'un fond blanc (255,255,255). Quel est le calcul pour calculer les valeurs RVB d'origine?
L'équation de mélange standard est:
out = alpha * new + (1 - alpha) * old
Où out
, new
et old
sont des couleurs RVB et alpha
est un nombre à virgule flottante dans la plage [0,1].
Donc, vous avez (pour le rouge):
240 = 0.1 * newR + 0.9 * 255
En résolvant pour newR
, nous obtenons:
newR = (240 - 0.9 * 255) / 0.1
qui équivaut à 105. Répétez pour les autres composants, et vous avez terminé.
Je me demande simplement pourquoi vous connaissez son alpha et non ses r, g, b ... À moins que le mode de fusion utilisé ne soit dans tous les cas normal, vous ne pourrez pas calculer la valeur d'origine. Et même si tout est idéal, vous ne pourrez qu'approximer, car certains arrondis ont probablement déjà eu lieu lors du passage de l'original au résultat. En outre, vous devrez probablement arrondir lorsque vous revenez du résultat à l'original.
Si le mode de fusion est Normal, ce n'est pas trop difficile :-)
opacity*original + (1-opacity)*background = resulting pixel
original R = (resulting R - ((1-opacity)*background R)) / opacity.
original G = (resulting G - ((1-opacity)*background G)) / opacity.
original B = (resulting B - ((1-opacity)*background B)) / opacity.
dans lequel l'opacité est (alpha/100)
.
Le pseudo-code suivant a résolu votre problème:
CalculateSolidColorFromTransparentColor(Color color, Color background)
{
alpha = color.A / 255;
oneminusalpha = 1 - alpha;
newR = ((color.R * alpha) + (oneminusalpha * background.R));
newG = ((color.G * alpha) + (oneminusalpha * background.G));
newB = ((color.B * alpha) + (oneminusalpha * background.B));
}
Notez que la couleur et l'arrière-plan d'entrée ont des valeurs exprimées en [0..255]