2010-02-27 21 views
12

Encontré esta secuencia de comandos RGB a HSL en http://www.mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript. No puedo encontrar otros pequeños decentes. El problema es que este código ni siquiera funciona realmente. ¿Alguien sabría por qué? (No sé un poco de matemáticas color, pero tal vez es devolver el complementaria?)¿Por qué no funciona este código Javascript RGB a HSL?

function rgbToHsl(r, g, b){ 
    r /= 255, g /= 255, b /= 255; 
    var max = Math.max(r, g, b), min = Math.min(r, g, b); 
    var h, s, l = (max + min)/2; 

    if(max == min){ 
     h = s = 0; // achromatic 
    }else{ 
     var d = max - min; 
     s = l > 0.5 ? d/(2 - max - min) : d/(max + min); 
     switch(max){ 
      case r: h = (g - b)/d + (g < b ? 6 : 0); break; 
      case g: h = (b - r)/d + 2; break; 
      case b: h = (r - g)/d + 4; break; 
     } 
     h /= 6; 
    } 

    return [h, s, l]; 
} 

Editar: cuando corro rgbToHsl(126,210,22) que me está dando [0,24, 0,81, 0,45], que es el HSL para un color naranja.

+0

título de la pregunta y el nombre de la función desajuste, ¿qué estás buscando RGB a HSL HSL o RGB? También muestre el código donde está usando esa función. – Sarfraz

+1

¿Cuál es el problema? ¿Qué valores son incorrectos? –

+4

Parece que me funciona, y cuando lo intento, sin duda devuelve una buena matriz HSL. ¿Qué es lo que te hace pensar que no funciona? Debe invocarlo con valores RGB expresados ​​como enteros decimales entre 0 y 255, si eso no está claro. – Pointy

Respuesta

21

La matriz HSV resultante se debe interpretar como tres fracciones. Para algunos programas, si desea expresar HSV como enteros, multiplique el valor "H" por 360 y los valores "S" y "V" por 100. El valor HSV que cita para su sombra verde RGB [126, 210, 22] es HSV [87, 81, 45] en números enteros. Se podría cambiar la función de devolver tales números enteros si quieres:

function rgbToHsl(r, g, b){ 
    r /= 255, g /= 255, b /= 255; 
    var max = Math.max(r, g, b), min = Math.min(r, g, b); 
    var h, s, l = (max + min)/2; 

    if(max == min){ 
     h = s = 0; // achromatic 
    }else{ 
     var d = max - min; 
     s = l > 0.5 ? d/(2 - max - min) : d/(max + min); 
     switch(max){ 
      case r: h = (g - b)/d + (g < b ? 6 : 0); break; 
      case g: h = (b - r)/d + 2; break; 
      case b: h = (r - g)/d + 4; break; 
     } 
     h /= 6; 
    } 

    return [Math.floor(h * 360), Math.floor(s * 100), Math.floor(l * 100)]; 
} 

[editar] que dijo, todavía me da algo con un brillo ("L" o "V") que es considerablemente demasiado oscuro; Gimp dice que el valor de HSV debe ser [90, 80, 82] o en términos fraccionarios [.20, .80, .82].

[otra edición] bien, un problema podría ser que HSL y HSV son diferentes esquemas ... sigue buscando.

Aceptar en caso de que alguien quiere RGB a HSV (parecido a lo que se ve en Gimp, por ejemplo) Aquí hay una versión de que:

function rgbToHsv(r, g, b) { 
    var 
     min = Math.min(r, g, b), 
     max = Math.max(r, g, b), 
     delta = max - min, 
     h, s, v = max; 

    v = Math.floor(max/255 * 100); 
    if (max != 0) 
     s = Math.floor(delta/max * 100); 
    else { 
     // black 
     return [0, 0, 0]; 
    } 

    if(r == max) 
     h = (g - b)/delta;   // between yellow & magenta 
    else if(g == max) 
     h = 2 + (b - r)/delta;  // between cyan & yellow 
    else 
     h = 4 + (r - g)/delta;  // between magenta & cyan 

    h = Math.floor(h * 60);   // degrees 
    if(h < 0) h += 360; 

    return [h, s, v]; 
} 
+1

Gracias hombre. ¡Esto funciona! Gracias a todos los que me llevaron aquí = D –

+0

'rgbToHsv (210, 210, 210)' división por '0' en' h = (g - b)/delta; ' – BrunoLM

+0

@BrunoLM sigue siendo la versión alfa 0.0.1: -) Sospecho que solo hará eso cuando le dé un color neutro (gris) - No estoy seguro de qué se debe hacer al respecto. Supongo que "tono" sería negro, la saturación sería del 100% y el valor sería el máximo/255 ¿tal vez? Tendría que jugar con eso un poco más. – Pointy

1

Función debajo convierte RGB color en el color Tono Saturación Brillo como Photoshop selector de color , los resultados están en los intervalos:

  • Hue 0-360 (grados)
  • Saturación: 0-100 (%)
  • Brillo: 0-100 (%)

Todavía no entiendo por qué la gente usa el término HSV (Tono Saturación Valor) en lugar de HSB (Tono Saturación Brillo), de todos modos es una cuestión fo terminología, los resultados son los mismos

//Converts to color HSB object (code from here http://www.csgnetwork.com/csgcolorsel4.html with some improvements) 
    function rgb2hsb(r, g, b) 
    {  
    r /= 255; g /= 255; b /= 255; // Scale to unity. 
    var minVal = Math.min(r, g, b), 
    maxVal = Math.max(r, g, b), 
    delta = maxVal - minVal, 
    HSB = {hue:0, sat:0, bri:maxVal}, 
    del_R, del_G, del_B; 

    if(delta !== 0) 
    { 
     HSB.sat = delta/maxVal; 
     del_R = (((maxVal - r)/6) + (delta/2))/delta; 
     del_G = (((maxVal - g)/6) + (delta/2))/delta; 
     del_B = (((maxVal - b)/6) + (delta/2))/delta; 

     if (r === maxVal) {HSB.hue = del_B - del_G;} 
     else if (g === maxVal) {HSB.hue = (1/3) + del_R - del_B;} 
     else if (b === maxVal) {HSB.hue = (2/3) + del_G - del_R;} 

     if (HSB.hue < 0) {HSB.hue += 1;} 
     if (HSB.hue > 1) {HSB.hue -= 1;} 
    } 

    HSB.hue *= 360; 
    HSB.sat *= 100; 
    HSB.bri *= 100; 

    return HSB; 
    } 
ejemplo

Uso:

var hsb = rgb2hsb(126,210,22); 
alert("hue = " + hsb.hue + "saturation = " + hsb.sat + "brightness = " + hsb.bri); 
Cuestiones relacionadas