web-dev-qa-db-fra.com

Comment calculer une couleur RVB en spécifiant une quantité de mélange alpha?

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?

53
user90598

L'équation de mélange standard est:

out = alpha * new + (1 - alpha) * old

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é.

89
unwind

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).

31
Peter Perháč

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]

4
Daniel Peñalba