Konvertieren von ARBG in RGB mit Alpha-Blending
Frage
Nehmen wir an, wir haben eine ARGB-Farbe:
Color argb = Color.FromARGB(127, 69, 12, 255); //Light Urple.
Wenn dies auf eine vorhandene Farbe aufgetragen wird, verschmelzen die Farben.Wenn es also mit Weiß gemischt wird, entsteht die Farbe Color.FromARGB(255, 162, 133, 255);
Die Lösung sollte so funktionieren:
Color blend = Color.White;
Color argb = Color.FromARGB(127, 69, 12, 255); //Light Urple.
Color rgb = ToRGB(argb, blend); //Same as Color.FromARGB(255, 162, 133, 255);
Was ist ToRGB
's Implementierung?
Lösung
Es heißt Alpha-Mischung.
Im Pseudocode wird davon ausgegangen, dass die Hintergrundfarbe (Mischung) immer 255 Alpha hat.Geht außerdem davon aus, dass Alpha 0-255 ist.
alpha=argb.alpha()
r = (alpha/255)*argb.r() + (1 - alpha/255)*blend.r()
g = (alpha/255)*argb.g() + (1 - alpha/255)*blend.g()
b = (alpha/255)*argb.b() + (1 - alpha/255)*blend.b()
Notiz:Je nach Sprache müssen Sie wahrscheinlich etwas (mehr) vorsichtig mit Gleitkomma-/Int-Mathematik und Rundungsproblemen sein.Zwischenprodukte entsprechend gießen
Bearbeitet, um Folgendes hinzuzufügen:
Wenn Sie keine Hintergrundfarbe mit einem Alpha von 255 haben, wird die Algebra viel komplizierter.Ich habe es schon einmal gemacht und es ist eine unterhaltsame Übung, die dem Leser überlassen bleibt (wenn Sie es wirklich wissen müssen, stellen Sie eine andere Frage :).
Mit anderen Worten: Welche Farbe C fügt sich in einen Hintergrund ein, genauso wie wenn man zuerst A und dann B überblendet.Das ist so etwas wie die Berechnung von A+B (was nicht dasselbe ist wie B+A).
Andere Tipps
Ich weiß, dass dies ein alter Thread ist, aber ich möchte Folgendes hinzufügen:
Public Shared Function AlphaBlend(ByVal ForeGround As Color, ByVal BackGround As Color) As Color
If ForeGround.A = 0 Then Return BackGround
If BackGround.A = 0 Then Return ForeGround
If ForeGround.A = 255 Then Return ForeGround
Dim Alpha As Integer = CInt(ForeGround.A) + 1
Dim B As Integer = Alpha * ForeGround.B + (255 - Alpha) * BackGround.B >> 8
Dim G As Integer = Alpha * ForeGround.G + (255 - Alpha) * BackGround.G >> 8
Dim R As Integer = Alpha * ForeGround.R + (255 - Alpha) * BackGround.R >> 8
Dim A As Integer = ForeGround.A
If BackGround.A = 255 Then A = 255
If A > 255 Then A = 255
If R > 255 Then R = 255
If G > 255 Then G = 255
If B > 255 Then B = 255
Return Color.FromArgb(Math.Abs(A), Math.Abs(R), Math.Abs(G), Math.Abs(B))
End Function
public static Color AlphaBlend(Color ForeGround, Color BackGround)
{
if (ForeGround.A == 0)
return BackGround;
if (BackGround.A == 0)
return ForeGround;
if (ForeGround.A == 255)
return ForeGround;
int Alpha = Convert.ToInt32(ForeGround.A) + 1;
int B = Alpha * ForeGround.B + (255 - Alpha) * BackGround.B >> 8;
int G = Alpha * ForeGround.G + (255 - Alpha) * BackGround.G >> 8;
int R = Alpha * ForeGround.R + (255 - Alpha) * BackGround.R >> 8;
int A = ForeGround.A;
if (BackGround.A == 255)
A = 255;
if (A > 255)
A = 255;
if (R > 255)
R = 255;
if (G > 255)
G = 255;
if (B > 255)
B = 255;
return Color.FromArgb(Math.Abs(A), Math.Abs(R), Math.Abs(G), Math.Abs(B));
}
Wenn Sie dieses Pre-Rendering nicht kennen müssen, können Sie meiner Meinung nach immer die Win32-Methode von getpixel verwenden.
Notiz:Ich tippe mitten in Missouri auf dem iPhone und habe keinen Internetzugang.Ich werde nach einem echten Win32-Beispiel suchen und prüfen, ob es ein .net-Äquivalent gibt.
Falls es jemanden interessiert und die oben gepostete (ausgezeichnete) Antwort nicht verwenden möchte, können Sie über diesen Link den Farbwert eines Pixels in .Net abrufen MSDN-Beispiel