2009-11-11 9 views
0

J'ai une couleur A que j'aimerais transformer en couleur C, en utilisant la couleur B. Donc, j'aimerais connaître la formule de mélange F dans GDI +, où F = F (A, B) = C A est la "couleur de fond" et B est une couleur d'incrustation au-dessus de A, qui, conjointement avec A donne C.Formule de mélange pour GDI +

vôtre,

// Magnus

+0

Je suppose que la couleur B est semi-transparente? – SLaks

+0

Si vous voulez dire que B a une valeur alpha inférieure à 1, yup :) – ralphtheninja

Répondre

2

Ceci est appelé Alpha Blending.

utiliser l'algorithme suivant pour le R, G, et les composants B, où alpha est compris entre 0 et 1.

newColor = MAX(255, (1 - alpha) * background + alpha * overlay) 
+0

Une seule valeur alpha pour l'arrière-plan et la superposition? Ou voulez-vous dire (1-alpha_background) * fond + alpha_overlay * superposition? – ralphtheninja

+0

Aaah ok, le fond est complètement opaque ici. – ralphtheninja

0

Fondamentalement (alpha, rouge vert et bleu sur une échelle de 0 à 1):

Result.Alpha = BackColor.Alpha + ForeColor.Alpha - (* BackColor.Alpha ForeColor.Alpha)
Result.Red = ((* ForeColor.Red ForeColor.Alpha) + (* BackColor.Red BackColor.Alpha * (1 - ForeColor.Alpha)))/Résultat.Alpha
(Remplacer «rouge» par «vert» et «bleu» ci-dessus pour obtenir le corr fonctions ÉPONDRE)

32 bits couleur, en VB.NET (un peu optimisé).

Shared Function Flatten(ByVal BackColor As Color, ByVal ForeColor As Color) As Color 
    If ForeColor.A = 0 Then Return BackColor ' Prevent division by zero 
    If ForeColor.A = 255 Then Return ForeColor ' Shortcut 

    Dim BackAlphaDbl As Single = CSng(BackColor.A) ' Convert to single to prevent in-calculation 8 bit overflow 
    Dim ForeAlphaDbl As Single = CSng(ForeColor.A) 

    Dim ForeAlphaNormalized As Single = ForeAlphaDbl/255 ' Precalculate for triple use 
    Dim BackcolorMultiplier As Single = BackAlphaDbl * (1 - ForeAlphaNormalized) ' Precalculate 

    Dim Alpha As Single = BackAlphaDbl + ForeAlphaDbl - BackAlphaDbl * ForeAlphaNormalized 

    Return Color.FromArgb(Alpha, (ForeColor.R * ForeAlphaDbl + BackColor.R * BackcolorMultiplier)/Alpha, (ForeColor.G * ForeAlphaDbl + BackColor.G * BackcolorMultiplier)/Alpha, (ForeColor.B * ForeAlphaDbl + BackColor.B * BackcolorMultiplier)/Alpha) 
End Function 

Je compris cela avec du papier et un crayon et vérifié par la superposition d'images avec GDI + et tester les couleurs résultantes . La seule différence entre cette fonction et GDI + est que GDI + arrondit de haut en bas de manière incohérente lorsque l'alpha du premier plan change. Cette fonction est plus précise.