72 votes

Comment changer une couleur RGB en HSV ?

Comment changer une couleur RGB en HSV ? En langage C#. Je recherche une méthode très rapide sans aucune bibliothèque externe.

34 votes

Pas un exact dupliqué. HSL != HSV.

0 votes

Que faire pour adapter le code du post HSL pour l'utiliser dans la solution HSV ?

8 votes

Wikipedia : Les deux sont mathématiquement cylindriques, mais HSV peut être considéré conceptuellement comme un cône inversé de couleurs, HSL représente conceptuellement un double-cône ou une sphère. Alors que la "teinte" dans HSL et HSV fait référence au même attribut, leurs définitions de la "saturation" diffèrent considérablement.

117voto

Greg Points 11248

Notez que Color.GetSaturation() et Color.GetBrightness() renvoient des valeurs HSL, et non HSV.
Le code suivant démontre la différence.

Color original = Color.FromArgb(50, 120, 200);
// original = {Name=ff3278c8, ARGB=(255, 50, 120, 200)}

double hue;
double saturation;
double value;
ColorToHSV(original, out hue, out saturation, out value);
// hue        = 212.0
// saturation = 0.75
// value      = 0.78431372549019607

Color copy = ColorFromHSV(hue, saturation, value);
// copy = {Name=ff3278c8, ARGB=(255, 50, 120, 200)}

// Compare that to the HSL values that the .NET framework provides: 
original.GetHue();        // 212.0
original.GetSaturation(); // 0.6
original.GetBrightness(); // 0.490196079

Le code C# suivant est ce que vous voulez. Il convertit entre RGB et HSV en utilisant les algorithmes décrits dans le document Wikipedia . Les plages sont de 0 à 360 pour hue et 0 - 1 pour saturation ou value .

public static void ColorToHSV(Color color, out double hue, out double saturation, out double value)
{
    int max = Math.Max(color.R, Math.Max(color.G, color.B));
    int min = Math.Min(color.R, Math.Min(color.G, color.B));

    hue = color.GetHue();
    saturation = (max == 0) ? 0 : 1d - (1d * min / max);
    value = max / 255d;
}

public static Color ColorFromHSV(double hue, double saturation, double value)
{
    int hi = Convert.ToInt32(Math.Floor(hue / 60)) % 6;
    double f = hue / 60 - Math.Floor(hue / 60);

    value = value * 255;
    int v = Convert.ToInt32(value);
    int p = Convert.ToInt32(value * (1 - saturation));
    int q = Convert.ToInt32(value * (1 - f * saturation));
    int t = Convert.ToInt32(value * (1 - (1 - f) * saturation));

    if (hi == 0)
        return Color.FromArgb(255, v, t, p);
    else if (hi == 1)
        return Color.FromArgb(255, q, v, p);
    else if (hi == 2)
        return Color.FromArgb(255, p, v, t);
    else if (hi == 3)
        return Color.FromArgb(255, p, q, v);
    else if (hi == 4)
        return Color.FromArgb(255, t, p, v);
    else
        return Color.FromArgb(255, v, p, q);
}

0 votes

Je pense que vous avez transposé les valeurs d'échantillon de Saturation et de Valeur dans votre réponse. Lorsque je convertis rgb(50,120,200) en Hue-Saturation-Value (HSV), j'obtiens hsv(212, 75%, 78.4%). En regardant les formules de wikipedia pour HSV : V=Max(r,g,b). Dans ce cas, max(50,120,200)=200. 200/255 = 0.7843

0 votes

Je vais juste modifier la réponse, en transposant les nombres Saturation et Valeur. La saturation devrait être 0,75, la valeur 0,7843...

0 votes

Savez-vous comment convertir la saturation de 0 à 1 en valeur de saturation utilisée par MS Paint (c'est-à-dire une échelle de 0 à 240) ?

24voto

georged Points 688

Avez-vous envisagé d'utiliser simplement l'espace de noms System.Drawing ? Par exemple :

System.Drawing.Color color = System.Drawing.Color.FromArgb(red, green, blue);
float hue = color.GetHue();
float saturation = color.GetSaturation();
float lightness = color.GetBrightness();

Notez qu'il ne s'agit pas exactement de ce que vous avez demandé (cf. différences entre HSL et HSV et la classe Color n'a pas de conversion à partir de HSL/HSV, mais cette dernière est raisonnable. facile à ajouter .

9 votes

Comme vous le soulignez, cela ne répond pas vraiment à la question car ces méthodes fournissent une conversion RVB vers HSL, et non RVB vers HSV.

3 votes

@greg : Je suis d'accord, cela conduira à des résultats terribles, comme je l'ai expérimenté moi-même.

13 votes

-1 : car ce n'est pas la réponse à la question. HSV est très différent de HSL. Note : HSV est parfois connu sous le nom de HSB (surtout dans Photoshop, et dans .NET).

7voto

Adam Rosenfield Points 176408

Voir Wikipedia . Il devrait être relativement simple de convertir ces formules en code. Faites simplement attention aux plages de vos entrées et sorties : s'agit-il de flottants entre 0 et 1, d'entiers entre 0 et 255, ou d'autre chose ?

6voto

BlaM Points 10753

Il y a une implémentation C ici :

http://www.cs.rit.edu/~ncs/color/t_convert.html

La conversion en C# devrait être très simple, car presque aucune fonction n'est appelée - seulement des calculs.

trouvé via Google

3 votes

Cette mise en œuvre n'est pas correcte. Elle semble être sur la base de cet exemple de code mais il manque une section (la partie normalisation). Cela m'a fait trébucher pendant un moment !

3voto

Captain Lepton Points 86

C'est la version VB.net qui fonctionne bien pour moi, portée à partir du code C dans le post de BlaM.

Il y a une implémentation C ici :

http://www.cs.rit.edu/~ncs/color/t_convert.html

La conversion en C# devrait être très simple, car presque aucune fonction n'est appelée - seulement des > calculs.


Public Sub HSVtoRGB(ByRef r As Double, ByRef g As Double, ByRef b As Double, ByVal h As Double, ByVal s As Double, ByVal v As Double)
    Dim i As Integer
    Dim f, p, q, t As Double

    If (s = 0) Then
        ' achromatic (grey)
        r = v
        g = v
        b = v
        Exit Sub
    End If

    h /= 60 'sector 0 to 5
    i = Math.Floor(h)
    f = h - i 'factorial part of h
    p = v * (1 - s)
    q = v * (1 - s * f)
    t = v * (1 - s * (1 - f))

    Select Case (i)
        Case 0
            r = v
            g = t
            b = p
            Exit Select
        Case 1
            r = q
            g = v
            b = p
            Exit Select
        Case 2
            r = p
            g = v
            b = t
            Exit Select
        Case 3
            r = p
            g = q
            b = v
            Exit Select
        Case 4
            r = t
            g = p
            b = v
            Exit Select
        Case Else   'case 5:
            r = v
            g = p
            b = q
            Exit Select
    End Select
End Sub

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X