2008-12-11 27 views
57

¿Cómo cambiar el color RGB a HSV? En lenguaje C#. Busco un método muy rápido sin ninguna biblioteca externa.¿Cómo cambiar el color RGB a HSV?

+31

No es un _exact_ duplicado. HSL! = HSV. –

+0

¿Qué hacer para adaptar el código de la publicación HSL para usar en la solución HSV? –

+7

Wikipedia: Ambos son matemáticamente cilíndricos, pero HSV puede considerarse conceptualmente como un cono de colores invertido, HSL conceptualmente representa un doble cono o esfera. Mientras que "hue" en HSL y HSV se refiere al mismo atributo, sus definiciones de "saturación" difieren drásticamente. – BlaM

Respuesta

26

¿ha considerado el simple uso de espacio de nombres System.Drawing? Por ejemplo:.

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

Tenga en cuenta que no es exactamente lo que lo solicitado (ver differences between HSL and HSV y la clase de color no tiene una conversión de vuelta de HSL/VHS pero el último es razonablemente easy to add

+4

Como usted señala, esto en realidad no responde la pregunta porque estos métodos proporcionan una conversión de RGB a HSL, no de RGB a HSV. – Greg

+3

@greg: Estoy de acuerdo, esto llevará a resultados terribles, ya que me he experimentado. – leppie

+11

-1: ya que esta no es la respuesta a la pregunta. HSV es muy diferente de HSL. * Nota *: HSV a veces se conoce como HSB (especialmente en Photoshop, y en .NET) –

5

Hay una aplicación C aquí:

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

debe ser muy sencillo para convertir a C#, ya que casi no hay funciones se llaman - sólo cálculos.

encontrar a través de Google

+1

Esta implementación no es correcta. Parece ser [basado en este código de ejemplo] (http://en.literateprograms.org/RGB_to_HSV_color_space_conversion_%28C%29) pero falta una sección (la parte de normalización). ¡Tuve un tropiezo por un tiempo! –

3

Este es la versión VB.net que funciona muy bien para mí portado a partir del código C en el post de Blam

Hay una aplicación C aquí:.

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

Debe ser muy sencillo convertir a C#, ya que casi no se llaman funciones - solo> cálculos.


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 
93

Tenga en cuenta que Color.GetSaturation()Color.GetBrightness() y los valores de retorno HSL, no HSV.
El siguiente código demuestra la diferencia.

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 

El siguiente código C# es lo que desea. Convierte entre RGB y HSV utilizando los algoritmos descritos en Wikipedia. Los rangos son 0 - 360 para hue, y 0 - 1 para saturation o 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

Creo que ha transpuesto los valores de muestra de Saturación y Valor en su respuesta. Cuando convierto rgb (50,120,200) en Hue-Saturation-Value (HSV) obtengo hsv (212, 75%, 78,4%). En cuanto a las fórmulas de wikipedia para HSV: V = Max (r, g, b). En este caso max (50,120,200) = 200. 200/255 = 0.7843 –

+0

Voy a editar la respuesta, transponiendo los números de Saturación y Valor. La saturación debe ser 0.75, el valor debe ser 0.7843 ... –

+0

¿Alguna idea de cómo convertir la saturación de 0-1 al valor de saturación que utiliza MS Paint (es decir, escala 0-240)? –

1

PRIMERO: asegúrese de que tiene un color como un mapa de bits, como esto: (! E es de la wich controlador de eventos recogido mi color)

Bitmap bmp = (Bitmap)pictureBox1.Image.Clone(); 
paintcolor = bmp.GetPixel(e.X, e.Y); 

lo que hice cuando tuve esta Problema Hace un rato, primero obtuve los valores de rgba (rojo, verde, azul y alfa). Luego creé 3 flotantes: tono flotante, saturación flotante, brillo flotante.Entonces sólo tiene que hacer:

hue = yourcolor.Gethue; 
saturation = yourcolor.GetSaturation; 
brightness = yourcolor.GetBrightness; 

La porción entera se ve así:

Bitmap bmp = (Bitmap)pictureBox1.Image.Clone(); 
      paintcolor = bmp.GetPixel(e.X, e.Y); 
      float hue; 
      float saturation; 
      float brightness; 
      hue = paintcolor.GetHue(); 
      saturation = paintcolor.GetSaturation(); 
      brightness = paintcolor.GetBrightness(); 

Si ahora quiere mostrarlos en una etiqueta, acaba de hacer:

yourlabelname.Text = hue.ToString; 
yourlabelname.Text = saturation.ToString; 
yourlabelname.Text = brightness.ToString; 

Aquí tiene , ahora tiene valores RGB en valores HSV :)

Espero que esto ayude