Ich versuche, eine Methode zu schreiben, die auf WPFs Color
struct funktioniert, um ein Byte zurückzugeben, das den Farbton des darstellt. Ich kämpfe mit der Formel, ich habe Komponententests für die Farbtöne Schwarz (255, 255, 255), Rot (255, 0, 0), Grün (0, 255, 0), Blau (0, 0, 255) geschrieben), Gelb (255, 255, 0), Cyan (0, 255, 255), Magenta (255, 0, 255) und Weiß (255, 255, 255) - sie alle außer Gelb (das 1 statt 42 zurückgibt)) und Magenta (die versucht, -1 anstelle von 212 zurückzugeben, schlägt jedoch fehl, da -1 nicht in ein Byte umgewandelt wird).Berechnen des Farbtons einer Farbe als 0 - 255 Bereich
Meine Erweiterungsmethoden für GetHue
wie folgt aussehen:
public static byte GetHue(this Color color)
=> GetHue(color.ToRgbDictionary(), color.GetMinComponent(), color.GetMaxComponent());
private static byte GetHue(Dictionary<ColorComponent, byte> rgbDictionary, ColorComponent minimumRgbComponent, ColorComponent maximumRgbComponent)
{
decimal chroma = rgbDictionary[maximumRgbComponent] - rgbDictionary[minimumRgbComponent];
return (byte)
(
chroma == 0
? 0
: thirdOfByte
* (byte)maximumRgbComponent
+
(
rgbDictionary[MathHelper.Wrap(maximumRgbComponent + 1)]
- rgbDictionary[MathHelper.Wrap(maximumRgbComponent - 1)]
)
/chroma
);
}
ToRgbDictionary
einfach die Color
in ein Wörterbuch seiner roten, grünen und blauen Komponenten dreht; ColorComponent
ist eine Enumeration, die als Schlüssel für diese Komponenten verwendet wird. MathHelper.Wrap
ist eine Methode, die eine Aufzählung in den deklarierten Bereich zurückbringt, wenn sie über- oder unterläuft. GetMinComponent
und sind zwei weitere Erweiterungsmethoden auf Color
, die die erste niedrigste und erste höchste ColorComponent
s der (wo die ColorComponent
Reihenfolge ist: Rot, Grün, Blau) zurückgeben. thirdOfByte
ist eine Konstante gleich byte.MaxValue/3
.
Ich habe basierend auf einem anderen diese Formel I hier (http://www.blackwasp.co.uk/rgbhsl_2.aspx), die wie folgt aussieht:
private decimal GetH(RGB rgb, decimal max, decimal chroma)
{
decimal h;
if (rgb.R == max)
h = ((rgb.G - rgb.B)/chroma);
else if (rgb.G == max)
h = ((rgb.B - rgb.R)/chroma) + 2M;
else
h = ((rgb.R - rgb.G)/chroma) + 4M;
return 60M * ((h + 6M) % 6M);
}
Das Problem mit dieser Formel wird es auf einen 0 zugeordnet wird - 360 Farbtonbereich, keine 0-255 Bereich, was ich brauche. Ich bin nicht sicher, was die konstanten Zahlen in dieser Formel tun, aber ich rate, dass die 60 etwas mit 360/3 = 120 zu tun hat, daher mein Drittel von Byte konstant, um zu versuchen, etwas Ähnliches zu tun. Was die 6M angeht, habe ich keine Ahnung woher sie kommen und warum sie zu diesem Zeitpunkt mit dem Farbtonwert addiert und modulisiert werden. Könnte mir jemand mit einem Sinn für Mathematik hier helfen?
UPDATE Der Grund für den 0-255 Bereich war, dass ich dachte, dass war alles, was es in einem anderen Stück Software verwendet gesehen erforderlich war, haben (wie dargestellt) für Farbton, Sättigung und Helligkeit. Dort habe ich auch den 42-Hue-Wert für Gelb erhalten. Ich versuche nun, den richtigen Bereich für Hues zu finden, um alle möglichen unterschiedlichen Farbtöne in einem 16777216 (256 * 256 * 256) Farbbereich abzudecken.
Ich bin überdenken mit 0-255 jetzt, dass du das gesagt hast; Ich möchte die Wertauflösung nicht verlieren, um 1 Byte zu sparen! Das bedeutet, dass ich die Formel jetzt kopieren könnte, aber ich würde es immer noch gerne verstehen (was ist die Bedeutung von 60M, die zwei 6Ms, die 4M und die 2M). Ich nehme an, dass der Modulus als Dezimalzahl wegen der nachfolgenden Multiplikation wichtig ist (nach der die Rundung angewendet werden könnte). – Sphynx
Nur um zu klären, ist 360 die Gesamtzahl der möglichen Farben für 255 * 255 * 255 Farben oder nur eine Möglichkeit, diese Hues in einen 1-Farbton-pro-Grad-Kreis abzubilden? Ich bin nach der Genauigkeit über die Kopplung von Farbtönen an die Form eines bestimmten Benutzersteuerelements. – Sphynx