Conversión de color de HSL a RGB

Estoy buscando una herramienta o el algoritmo para convertir entre color HSL a RGB. Me parece que HSL no se usa mucho, así que no estoy teniendo mucha suerte en la búsqueda de un convertidor.

Garry Tan publicó una solución de Javascript en su blog (que él atribuye a un ahora desaparecido mjijackson.com, pero está archivado aquí y el autor original tiene una esencia , gracias a user2441511).

El código se vuelve a publicar a continuación:

HSL a RGB:

 /** * Converts an HSL color value to RGB. Conversion formula * adapted from http://en.wikipedia.org/wiki/HSL_color_space. * Assumes h, s, and l are contained in the set [0, 1] and * returns r, g, and b in the set [0, 255]. * * @param {number} h The hue * @param {number} s The saturation * @param {number} l The lightness * @return {Array} The RGB representation */ function hslToRgb(h, s, l){ var r, g, b; if(s == 0){ r = g = b = l; // achromatic }else{ var hue2rgb = function hue2rgb(p, q, t){ if(t < 0) t += 1; if(t > 1) t -= 1; if(t < 1/6) return p + (q - p) * 6 * t; if(t < 1/2) return q; if(t < 2/3) return p + (q - p) * (2/3 - t) * 6; return p; } var q = l < 0.5 ? l * (1 + s) : l + s - l * s; var p = 2 * l - q; r = hue2rgb(p, q, h + 1/3); g = hue2rgb(p, q, h); b = hue2rgb(p, q, h - 1/3); } return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; } 

RGB a HSL:

 /** * Converts an RGB color value to HSL. Conversion formula * adapted from http://en.wikipedia.org/wiki/HSL_color_space. * Assumes r, g, and b are contained in the set [0, 255] and * returns h, s, and l in the set [0, 1]. * * @param {number} r The red color value * @param {number} g The green color value * @param {number} b The blue color value * @return {Array} The HSL representation */ 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]; } 

Encontré la manera más fácil, python al rescate : D

colorsys.hls_to_rgb(h, l, s)

Convierta el color de las coordenadas HLS a las coordenadas RGB.

El artículo para HSL y HSV en wikipedia contiene algunas fórmulas. Los cálculos son un poco complicados, por lo que podría ser útil echar un vistazo a las implementaciones existentes .

Si está buscando algo que definitivamente se ajuste a la semántica CSS para HSL y RGB, podría usar el algoritmo especificado en la especificación CSS 3 , que dice:

 HOW TO RETURN hsl.to.rgb(h, s, l): SELECT: l<=0.5: PUT l*(s+1) IN m2 ELSE: PUT l+sl*s IN m2 PUT l*2-m2 IN m1 PUT hue.to.rgb(m1, m2, h+1/3) IN r PUT hue.to.rgb(m1, m2, h ) IN g PUT hue.to.rgb(m1, m2, h-1/3) IN b RETURN (r, g, b) HOW TO RETURN hue.to.rgb(m1, m2, h): IF h<0: PUT h+1 IN h IF h>1: PUT h-1 IN h IF h*6<1: RETURN m1+(m2-m1)*h*6 IF h*2<1: RETURN m2 IF h*3<2: RETURN m1+(m2-m1)*(2/3-h)*6 RETURN m1 

Creo que esta es la fuente de algunas de las otras respuestas aquí.

Implementación de Java del código de Mohsen

Tenga en cuenta que todos los números enteros se declaran como flotantes (es decir, 1f) y deben ser flotantes, de lo contrario optarán por los colores grises.

HSL a RGB

  /** * Converts an HSL color value to RGB. Conversion formula * adapted from http://en.wikipedia.org/wiki/HSL_color_space. * Assumes h, s, and l are contained in the set [0, 1] and * returns r, g, and b in the set [0, 255]. * * @param h The hue * @param s The saturation * @param l The lightness * @return int array, the RGB representation */ public static int[] hslToRgb(float h, float s, float l){ float r, g, b; if (s == 0f) { r = g = b = l; // achromatic } else { float q = l < 0.5f ? l * (1 + s) : l + s - l * s; float p = 2 * l - q; r = hueToRgb(p, q, h + 1f/3f); g = hueToRgb(p, q, h); b = hueToRgb(p, q, h - 1f/3f); } int[] rgb = {(int) (r * 255), (int) (g * 255), (int) (b * 255)}; return rgb; } /** Helper method that converts hue to rgb */ public static float hueToRgb(float p, float q, float t) { if (t < 0f) t += 1f; if (t > 1f) t -= 1f; if (t < 1f/6f) return p + (q - p) * 6f * t; if (t < 1f/2f) return q; if (t < 2f/3f) return p + (q - p) * (2f/3f - t) * 6f; return p; } 

RGB a HSL

 /** * Converts an RGB color value to HSL. Conversion formula * adapted from http://en.wikipedia.org/wiki/HSL_color_space. * Assumes pR, pG, and bpBare contained in the set [0, 255] and * returns h, s, and l in the set [0, 1]. * * @param pR The red color value * @param pG The green color value * @param pB The blue color value * @return float array, the HSL representation */ public static float[] rgbToHsl(int pR, int pG, int pB) { float r = pR / 255f; float g = pG / 255f; float b = pB / 255f; float max = (r > g && r > b) ? r : (g > b) ? g : b; float min = (r < g && r < b) ? r : (g < b) ? g : b; float h, s, l; l = (max + min) / 2.0f; if (max == min) { h = s = 0.0f; } else { float d = max - min; s = (l > 0.5f) ? d / (2.0f - max - min) : d / (max + min); if (r > g && r > b) h = (g - b) / d + (g < b ? 6.0f : 0.0f); else if (g > b) h = (b - r) / d + 2.0f; else h = (r - g) / d + 4.0f; h /= 6.0f; } float[] hsl = {h, s, l}; return hsl; } 

C # Código de la respuesta de Mohsen.

Aquí está el código de la respuesta de Mohsen en C # si alguien más lo quiere. Nota: el Color es una clase personalizada y Vector4 es de OpenTK. Ambos son fáciles de reemplazar con otra cosa de su elección.

Hsl a Rgba

 ///  /// Converts an HSL color value to RGB. /// Input: Vector4 ( X: [0.0, 1.0], Y: [0.0, 1.0], Z: [0.0, 1.0], W: [0.0, 1.0] ) /// Output: Color ( R: [0, 255], G: [0, 255], B: [0, 255], A: [0, 255] ) ///  /// Vector4 defining X = h, Y = s, Z = l, W = a. Ranges [0, 1.0] /// RGBA Color. Ranges [0, 255] public static Color HslToRgba(Vector4 hsl) { float r, g, b; if (hsl.Y == 0.0f) r = g = b = hsl.Z; else { var q = hsl.Z < 0.5f ? hsl.Z * (1.0f + hsl.Y) : hsl.Z + hsl.Y - hsl.Z * hsl.Y; var p = 2.0f * hsl.Z - q; r = HueToRgb(p, q, hsl.X + 1.0f / 3.0f); g = HueToRgb(p, q, hsl.X); b = HueToRgb(p, q, hsl.X - 1.0f / 3.0f); } return new Color((int)(r * 255), (int)(g * 255), (int)(b * 255), (int)(hsl.W * 255)); } // Helper for HslToRgba private static float HueToRgb(float p, float q, float t) { if (t < 0.0f) t += 1.0f; if (t > 1.0f) t -= 1.0f; if (t < 1.0f / 6.0f) return p + (q - p) * 6.0f * t; if (t < 1.0f / 2.0f) return q; if (t < 2.0f / 3.0f) return p + (q - p) * (2.0f / 3.0f - t) * 6.0f; return p; } 

Rgba a Hsl

 ///  /// Converts an RGB color value to HSL. /// Input: Color ( R: [0, 255], G: [0, 255], B: [0, 255], A: [0, 255] ) /// Output: Vector4 ( X: [0.0, 1.0], Y: [0.0, 1.0], Z: [0.0, 1.0], W: [0.0, 1.0] ) ///  ///  ///  public static Vector4 RgbaToHsl(Color rgba) { float r = rgba.R / 255.0f; float g = rgba.G / 255.0f; float b = rgba.B / 255.0f; float max = (r > g && r > b) ? r : (g > b) ? g : b; float min = (r < g && r < b) ? r : (g < b) ? g : b; float h, s, l; h = s = l = (max + min) / 2.0f; if (max == min) h = s = 0.0f; else { float d = max - min; s = (l > 0.5f) ? d / (2.0f - max - min) : d / (max + min); if (r > g && r > b) h = (g - b) / d + (g < b ? 6.0f : 0.0f); else if (g > b) h = (b - r) / d + 2.0f; else h = (r - g) / d + 4.0f; h /= 6.0f; } return new Vector4(h, s, l, rgba.A / 255.0f); } 

Implementación de Php del código de C # de Chris

También desde aquí , lo cual explica muy bien las matemáticas.

Esto es básicamente un conjunto de funciones para convertir hacia y desde HSL (Luminosidad de saturación de tonos)

Probado y trabajando en PHP 5.6.15

TL; DR : el código completo se puede encontrar aquí en Pastebin .


Hexagonal a HSL

Entrada: color hexadecimal en formato: [#] 0f4 o [#] 00ff44 (signo de libra opcional)
Salida: HSL en grados, porcentaje, porcentaje

 /** * Input: hex color * Output: hsl(in ranges from 0-1) * * Takes the hex, converts it to RGB, and sends * it to RGBToHsl. Returns the output. * */ function hexToHsl($hex) { $r = ""; $g = ""; $b = ""; $hex = str_replace('#', '', $hex); if (strlen($hex) == 3) { $r = substr($hex, 0, 1); $r = $r . $r; $g = substr($hex, 1, 1); $g = $g . $g; $b = substr($hex, 2, 1); $b = $b . $b; } elseif (strlen($hex) == 6) { $r = substr($hex, 0, 2); $g = substr($hex, 2, 2); $b = substr($hex, 4, 2); } else { return false; } $r = hexdec($r); $g = hexdec($g); $b = hexdec($b); $hsl = rgbToHsl($r,$g,$b); return $hsl; } 

RGB a HSL

Entrada: RGB en el rango 0-255 Salida: HSL en Grados, Porcentaje, Porcentaje.

 /** * *Credits: * https://stackoverflow.com/questions/4793729/rgb-to-hsl-and-back-calculation-problems * http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/ * * Called by hexToHsl by default. * * Converts an RGB color value to HSL. Conversion formula * adapted from http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/. * Assumes r, g, and b are contained in the range [0 - 255] and * returns h, s, and l in the format Degrees, Percent, Percent. * * @param Number r The red color value * @param Number g The green color value * @param Number b The blue color value * @return Array The HSL representation */ function rgbToHsl($r, $g, $b){ //For the calculation, rgb needs to be in the range from 0 to 1. To convert, divide by 255 (ff). $r /= 255; $g /= 255; $b /= 255; $myMax = max($r, $g, $b); $myMin = min($r, $g, $b); $maxAdd = ($myMax + $myMin); $maxSub = ($myMax - $myMin); //luminence is (max + min)/2 $h = 0; $s = 0; $l = ($maxAdd / 2.0); //if all the numbers are equal, there is no saturation (greyscale). if($myMin != $myMax){ if ($l < 0.5) { $s = ($maxSub / $maxAdd); } else { $s = (2.0 - $myMax - $myMin); //note order of opperations - can't use $maxSub here $s = ($maxSub / $s); } //find hue switch($myMax){ case $r: $h = ($g - $b); $h = ($h / $maxSub); break; case $g: $h = ($b - $r); $h = ($h / $maxSub); $h = ($h + 2.0); break; case $b: $h = ($r - $g); $h = ($h / $maxSub); $h = ($h + 4.0); break; } } $hsl = hslToDegPercPerc($h, $s, $l); return $hsl; } 

Formato HSL (rango 0-1) a Grados, Porcentaje, Porcentaje

Para los cálculos matemáticos, HSL es más fácil de tratar en el rango 0-1, pero para la legibilidad humana, es más fácil en Grados, Porcentaje, Porcentaje. Esta función toma HSL en los rangos 0-1, y devuelve HSL en Grados, Porcentaje, Porcentaje.

 /** * Input: HSL in ranges 0-1. * Output: HSL in format Deg, Perc, Perc. * * Note: rgbToHsl calls this function by default. * * Multiplies $h by 60, and $s and $l by 100. */ function hslToDegPercPerc($h, $s, $l) { //convert h to degrees $h *= 60; if ($h < 0) { $h += 360; } //convert s and l to percentage $s *= 100; $l *= 100; $hsl['h'] = $h; $hsl['s'] = $s; $hsl['l'] = $l; return $hsl; } 

HSL (grados, porcentaje, formato de porcentaje) a HSL en el rango 0-1

Esta función convierte HSL en el formato Degrees, Percent, Percent, en los rangos 0-1 para facilitar el cálculo.

 /** * Input: HSL in format Deg, Perc, Perc * Output: An array containing HSL in ranges 0-1 * * Divides $h by 60, and $s and $l by 100. * * hslToRgb calls this by default. */ function degPercPercToHsl($h, $s, $l) { //convert h, s, and l back to the 0-1 range //convert the hue's 360 degrees in a circle to 1 $h /= 360; //convert the saturation and lightness to the 0-1 //range by multiplying by 100 $s /= 100; $l /= 100; $hsl['h'] = $h; $hsl['s'] = $s; $hsl['l'] = $l; return $hsl; } 

HSL a RGB

Entrada: HSL en el formato Grados, Porcentaje, Porcentaje de Salida: RGB en el formato 255, 255, 255 .

 /** * Converts an HSL color value to RGB. Conversion formula * adapted from http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/. * Assumes h, s, and l are in the format Degrees, * Percent, Percent, and returns r, g, and b in * the range [0 - 255]. * * Called by hslToHex by default. * * Calls: * degPercPercToHsl * hueToRgb * * @param Number h The hue value * @param Number s The saturation level * @param Number l The luminence * @return Array The RGB representation */ function hslToRgb($h, $s, $l){ $hsl = degPercPercToHsl($h, $s, $l); $h = $hsl['h']; $s = $hsl['s']; $l = $hsl['l']; //If there's no saturation, the color is a greyscale, //so all three RGB values can be set to the lightness. //(Hue doesn't matter, because it's grey, not color) if ($s == 0) { $r = $l * 255; $g = $l * 255; $b = $l * 255; } else { //calculate some temperary variables to make the //calculation eaisier. if ($l < 0.5) { $temp2 = $l * (1 + $s); } else { $temp2 = ($l + $s) - ($s * $l); } $temp1 = 2 * $l - $temp2; //run the calculated vars through hueToRgb to //calculate the RGB value. Note that for the Red //value, we add a third (120 degrees), to adjust //the hue to the correct section of the circle for //red. Simalarly, for blue, we subtract 1/3. $r = 255 * hueToRgb($temp1, $temp2, $h + (1 / 3)); $g = 255 * hueToRgb($temp1, $temp2, $h); $b = 255 * hueToRgb($temp1, $temp2, $h - (1 / 3)); } $rgb['r'] = $r; $rgb['g'] = $g; $rgb['b'] = $b; return $rgb; } 

Hue a RGB

Esta función es llamada por hslToRgb para convertir el tono en los valores RGB separados.

 /** * Converts an HSL hue to it's RGB value. * * Input: $temp1 and $temp2 - temperary vars based on * whether the lumanence is less than 0.5, and * calculated using the saturation and luminence * values. * $hue - the hue (to be converted to an RGB * value) For red, add 1/3 to the hue, green * leave it alone, and blue you subtract 1/3 * from the hue. * * Output: One RGB value. * * Thanks to Easy RGB for this function (Hue_2_RGB). * http://www.easyrgb.com/index.php?X=MATH&$h=19#text19 * */ function hueToRgb($temp1, $temp2, $hue) { if ($hue < 0) { $hue += 1; } if ($hue > 1) { $hue -= 1; } if ((6 * $hue) < 1 ) { return ($temp1 + ($temp2 - $temp1) * 6 * $hue); } elseif ((2 * $hue) < 1 ) { return $temp2; } elseif ((3 * $hue) < 2 ) { return ($temp1 + ($temp2 - $temp1) * ((2 / 3) - $hue) * 6); } return $temp1; } 

HSL a maleficio

Entrada: HSL en formato Degrees, Percent, Percent Output: Hex en formato 00ff22 (sin signo de libra).

Convierte a RGB, luego se convierte por separado a hexadecimal.

 /** * Converts HSL to Hex by converting it to * RGB, then converting that to hex. * * string hslToHex($h, $s, $l[, $prependPound = true] * * $h is the Degrees value of the Hue * $s is the Percentage value of the Saturation * $l is the Percentage value of the Lightness * $prependPound is a bool, whether you want a pound * sign prepended. (optional - default=true) * * Calls: * hslToRgb * * Output: Hex in the format: #00ff88 (with * pound sign). Rounded to the nearest whole * number. */ function hslToHex($h, $s, $l, $prependPound = true) { //convert hsl to rgb $rgb = hslToRgb($h,$s,$l); //convert rgb to hex $hexR = $rgb['r']; $hexG = $rgb['g']; $hexB = $rgb['b']; //round to the nearest whole number $hexR = round($hexR); $hexG = round($hexG); $hexB = round($hexB); //convert to hex $hexR = dechex($hexR); $hexG = dechex($hexG); $hexB = dechex($hexB); //check for a non-two string length //if it's 1, we can just prepend a //0, but if it is anything else non-2, //it must return false, as we don't //know what format it is in. if (strlen($hexR) != 2) { if (strlen($hexR) == 1) { //probably in format #0f4, etc. $hexR = "0" . $hexR; } else { //unknown format return false; } } if (strlen($hexG) != 2) { if (strlen($hexG) == 1) { $hexG = "0" . $hexG; } else { return false; } } if (strlen($hexB) != 2) { if (strlen($hexB) == 1) { $hexB = "0" . $hexB; } else { return false; } } //if prependPound is set, will prepend a //# sign to the beginning of the hex code. //(default = true) $hex = ""; if ($prependPound) { $hex = "#"; } $hex = $hex . $hexR . $hexG . $hexB; return $hex; } 

Así es como lo hago, lo que es fácil de recordar es pensar en RGB como tres radios en una rueda, a 120 grados de separación.

 H = hue (0-360) S = saturation (0-1) L = luminance (0-1) R1 = SIN( H ) * L G1 = SIN( H + 120 ) * L B1 = SIN( H + 240 ) * L 

La parte difícil es la saturación, que se reduce a la media de esos tres.

 AVERAGE = (R1 + G1 + B1) / 3 R2 = ((R1 - AVERAGE) * S) + AVERAGE G2 = ((G1 - AVERAGE) * S) + AVERAGE B2 = ((B1 - AVERAGE) * S) + AVERAGE RED = R2 * 255 GREEN = G2 * 255 BLUE = B2 * 255 

Aquí está la función javascript modificada, emite Hue en el conjunto 0-360 grados.

 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 ; break; case g: h = 2 + ( (b - r) / d); break; case b: h = 4 + ( (r - g) / d); break; } h*=60; if (h < 0) h +=360; } return([h, s, l]); } alert(rgbToHsl(125,115,145)); 

Aquí hay una versión rápida, súper simple y sin sucursales en GLSL:

 vec3 hsl2rgb( vec3 c ) { vec3 rgb = clamp(abs(mod(cx*6.0 + vec3(0.0, 4.0, 2.0), 6.0)-3.0)-1.0, 0.0, 1.0); return cz + cy * (rgb-0.5)*(1.0-abs(2.0*cz-1.0)); } 

No es mucho más corto que eso ~


Enlace a la prueba de concepto original: https://www.shadertoy.com/view/XljGzV

(Descargo de responsabilidad: ¡no es mi código!)

Unity3D C # Código de la respuesta de Mohsen.

Aquí está el código de la respuesta de Mohsen en C # específicamente para Unity3D. Fue adaptado de la respuesta C # dada por Alec Thilenius arriba.

 using UnityEngine; using System.Collections; public class ColorTools { ///  /// Converts an HSL color value to RGB. /// Input: Vector4 ( X: [0.0, 1.0], Y: [0.0, 1.0], Z: [0.0, 1.0], W: [0.0, 1.0] )**strong text** /// Output: Color ( R: [0.0, 1.0], G: [0.0, 1.0], B: [0.0, 1.0], A: [0.0, 1.0] ) ///  /// Vector4 defining X = h, Y = s, Z = l, W = a. Ranges [0, 1.0] /// RGBA Color. Ranges [0.0, 1.0] public static Color HslToRgba(Vector4 hsl) { float r, g, b; if (hsl.y == 0.0f) r = g = b = hsl.z; else { var q = hsl.z < 0.5f ? hsl.z * (1.0f + hsl.y) : hsl.z + hsl.y - hsl.z * hsl.y; var p = 2.0f * hsl.z - q; r = HueToRgb(p, q, hsl.x + 1.0f / 3.0f); g = HueToRgb(p, q, hsl.x); b = HueToRgb(p, q, hsl.x - 1.0f / 3.0f); } return new Color(r, g, b, hsl.w); } // Helper for HslToRgba private static float HueToRgb(float p, float q, float t) { if (t < 0.0f) t += 1.0f; if (t > 1.0f) t -= 1.0f; if (t < 1.0f / 6.0f) return p + (q - p) * 6.0f * t; if (t < 1.0f / 2.0f) return q; if (t < 2.0f / 3.0f) return p + (q - p) * (2.0f / 3.0f - t) * 6.0f; return p; } ///  /// Converts an RGB color value to HSL. /// Input: Color ( R: [0.0, 1.0], G: [0.0, 1.0], B: [0.0, 1.0], A: [0.0, 1.0] ) /// Output: Vector4 ( X: [0.0, 1.0], Y: [0.0, 1.0], Z: [0.0, 1.0], W: [0.0, 1.0] ) ///  ///  ///  public static Vector4 RgbaToHsl(Color rgba) { float max = (rgba.r > rgba.g && rgba.r > rgba.b) ? rgba.r : (rgba.g > rgba.b) ? rgba.g : rgba.b; float min = (rgba.r < rgba.g && rgba.r < rgba.b) ? rgba.r : (rgba.g < rgba.b) ? rgba.g : rgba.b; float h, s, l; h = s = l = (max + min) / 2.0f; if (max == min) h = s = 0.0f; else { float d = max - min; s = (l > 0.5f) ? d / (2.0f - max - min) : d / (max + min); if (rgba.r > rgba.g && rgba.r > rgba.b) h = (rgba.g - rgba.b) / d + (rgba.g < rgba.b ? 6.0f : 0.0f); else if (rgba.g > rgba.b) h = (rgba.b - rgba.r) / d + 2.0f; else h = (rgba.r - rgba.g) / d + 4.0f; h /= 6.0f; } return new Vector4(h, s, l, rgba.a); } } 

Para todos los que dijeron que la solución Garry Tan convertía incorrectamente de RGB a HSL y viceversa. Es porque dejó fuera parte de la fracción del número en su código. Corregí su código (javascript). Lo siento por un enlace en languadge ruso, pero en inglés ausente – HSL-wiki

 function toHsl(r, g, b) { r /= 255.0; g /= 255.0; b /= 255.0; var max = Math.max(r, g, b); var min = Math.min(r, g, b); var h, s, l = (max + min) / 2.0; if(max == min) { h = s = 0; } else { var d = max - min; s = (l > 0.5 ? d / (2.0 - max - min) : d / (max + min)); if(max == r && g >= b) { h = 1.0472 * (g - b) / d ; } else if(max == r && g < b) { h = 1.0472 * (g - b) / d + 6.2832; } else if(max == g) { h = 1.0472 * (b - r) / d + 2.0944; } else if(max == b) { h = 1.0472 * (r - g) / d + 4.1888; } } return { str: 'hsl(' + parseInt(h / 6.2832 * 360.0 + 0.5) + ',' + parseInt(s * 100.0 + 0.5) + '%,' + parseInt(l * 100.0 + 0.5) + '%)', obj: { h: parseInt(h / 6.2832 * 360.0 + 0.5), s: parseInt(s * 100.0 + 0.5), l: parseInt(l * 100.0 + 0.5) } }; }; 

Lo obtuve del código fuente de HSL Picker de Brandon Mathis.

Fue escrito originalmente en CoffeeScript . Lo convertí a JavaScript usando un convertidor en línea, y saqué el mecanismo para verificar que la entrada del usuario era un valor RGB válido. Esta respuesta funcionó para mi caso de uso, ya que la respuesta más votada en esta publicación me pareció no producir un valor de HSL válido.

Tenga en cuenta que devuelve un valor hsla , con a representación de opacidad / transparencia. 0 es completamente transparente y 1 completamente opaco.

 function rgbToHsl(rgb) { var a, add, b, diff, g, h, hue, l, lum, max, min, r, s, sat; r = parseFloat(rgb[0]) / 255; g = parseFloat(rgb[1]) / 255; b = parseFloat(rgb[2]) / 255; max = Math.max(r, g, b); min = Math.min(r, g, b); diff = max - min; add = max + min; hue = min === max ? 0 : r === max ? ((60 * (g - b) / diff) + 360) % 360 : g === max ? (60 * (b - r) / diff) + 120 : (60 * (r - g) / diff) + 240; lum = 0.5 * add; sat = lum === 0 ? 0 : lum === 1 ? 1 : lum <= 0.5 ? diff / add : diff / (2 - add); h = Math.round(hue); s = Math.round(sat * 100); l = Math.round(lum * 100); a = parseFloat(rgb[3]) || 1; return [h, s, l, a]; } 

Con H, S y L en el rango [0,1]:

 ConvertHslToRgb: function (iHsl) { var min, sv, sextant, fract, vsf; var v = (iHsl.l <= 0.5) ? (iHsl.l * (1 + iHsl.s)) : (iHsl.l + iHsl.s - iHsl.l * iHsl.s); if (v === 0) return { Red: 0, Green: 0, Blue: 0 }; min = 2 * iHsl.l - v; sv = (v - min) / v; var h = (6 * iHsl.h) % 6; sextant = Math.floor(h); fract = h - sextant; vsf = v * sv * fract; switch (sextant) { case 0: return { r: v, g: min + vsf, b: min }; case 1: return { r: v - vsf, g: v, b: min }; case 2: return { r: min, g: v, b: min + vsf }; case 3: return { r: min, g: v - vsf, b: v }; case 4: return { r: min + vsf, g: min, b: v }; case 5: return { r: v, g: min, b: v - vsf }; } } 

Para cuando necesita RGB a HSV y viceversa:

 function rgbToHsv(r, g, b) { r /= 255, g /= 255, b /= 255; var min = Math.min(r, g, b), max = Math.max(r, g, b), delta = max - min, h = 0, s = 0, v = max; if (min != max) { s = (delta / max); switch (max) { case r: h = (g - b) / delta + (g < b ? 6 : 0); break; case g: h = (b - r) / delta + 2; break; case b: h = (r - g) / delta + 4; break; } h /= 6; } return [h, s, v]; } function hsvToRgb(h, s, v) { var step = h / (1 / 6), pos = step - Math.floor(step), // the hue position within the current step m = (Math.floor(step) % 2) ? (1 - pos) * v : pos * v, // mix color value adjusted to the brightness(v) max = 1 * v, min = (1 - s) * v, med = m + ((1 - s) * (v - m)), r, g, b; switch (Math.floor(step)) { case 0: r = max; g = med; b = min; break; case 1: r = med; g = max; b = min; break; case 2: r = min; g = max; b = med; break; case 3: r = min; g = med; b = max; break; case 4: r = med; g = min; b = max; break; case 5: r = max; g = min; b = med; break; } return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; } 

Necesitaba uno muy ligero, no es 100%, pero se acerca lo suficiente para algunos usos.

 float3 Hue(float h, float s, float l) { float r = max(cos(h * 2 * UNITY_PI) * 0.5 + 0.5, 0); float g = max(cos((h + 0.666666) * 2 * UNITY_PI) * 0.5 + 0.5, 0); float b = max(cos((h + 0.333333) * 2 * UNITY_PI) * 0.5 + 0.5, 0); float gray = 0.2989 * r + 0.5870 * g + 0.1140 * b; return lerp(gray, float3(r, g, b), s) * smoothstep(0, 0.5, l) + 1 * smoothstep(0.5, 1, l); } 

Implementación de PHP del código de @ Mohsen (incluido Test!)

Perdón por volver a publicar esto. Pero realmente no he visto ninguna otra implementación que ofrezca la calidad que necesitaba.

 /** * Converts an HSL color value to RGB. Conversion formula * adapted from http://en.wikipedia.org/wiki/HSL_color_space. * Assumes h, s, and l are contained in the set [0, 1] and * returns r, g, and b in the set [0, 255]. * * @param {number} h The hue * @param {number} s The saturation * @param {number} l The lightness * @return {Array} The RGB representation */ function hue2rgb($p, $q, $t){ if($t < 0) $t += 1; if($t > 1) $t -= 1; if($t < 1/6) return $p + ($q - $p) * 6 * $t; if($t < 1/2) return $q; if($t < 2/3) return $p + ($q - $p) * (2/3 - $t) * 6; return $p; } function hslToRgb($h, $s, $l){ if($s == 0){ $r = $l; $g = $l; $b = $l; // achromatic }else{ $q = $l < 0.5 ? $l * (1 + $s) : $l + $s - $l * $s; $p = 2 * $l - $q; $r = hue2rgb($p, $q, $h + 1/3); $g = hue2rgb($p, $q, $h); $b = hue2rgb($p, $q, $h - 1/3); } return array(round($r * 255), round($g * 255), round($b * 255)); } /* Uncomment to test * / for ($i=0;$i<360;$i++) { $rgb=hslToRgb($i/360, 1, .9); echo '
'; } /* End Test */

Un valor de color hsl | a, establecido en javascript, se convertirá instantáneamente a rgb | a. Todo lo que necesita hacer es acceder al valor de estilo calculado

 document.body.style.color = 'hsla(44, 100%, 50%, 0.8)'; console.log(window.getComputedStyle(document.body).color); // displays: rgba(255, 187, 0, 0.8) 

Técnicamente, supongo, esto no es ninguna línea de código, simplemente se hace automáticamente. Entonces, dependiendo de su entorno, es posible que pueda salirse con la suya con esto. No es que no haya muchas respuestas muy reflexivas aquí. No sé cuál es tu objective.

Ahora, ¿y si quieres convertir de rbg | a a hsl | a?

Implementación en C ++ con probablemente un mejor rendimiento que el código @Mohsen. Utiliza un rango [0-6] para el tono, evitando la división y la multiplicación por 6. El rango S y L es [0,1]

 void fromRGBtoHSL(float rgb[], float hsl[]) { const float maxRGB = max(rgb[0], max(rgb[1], rgb[2])); const float minRGB = min(rgb[0], min(rgb[1], rgb[2])); const float delta2 = maxRGB + minRGB; hsl[2] = delta2 * 0.5f; const float delta = maxRGB - minRGB; if (delta < FLT_MIN) hsl[0] = hsl[1] = 0.0f; else { hsl[1] = delta / (hsl[2] > 0.5f ? 2.0f - delta2 : delta2); if (rgb[0] >= maxRGB) { hsl[0] = (rgb[1] - rgb[2]) / delta; if (hsl[0] < 0.0f) hsl[0] += 6.0f; } else if (rgb[1] >= maxRGB) hsl[0] = 2.0f + (rgb[2] - rgb[0]) / delta; else hsl[0] = 4.0f + (rgb[0] - rgb[1]) / delta; } } void fromHSLtoRGB(const float hsl[], float rgb[]) { if(hsl[1] < FLT_MIN) rgb[0] = rgb[1] = rgb[2] = hsl[2]; else if(hsl[2] < FLT_MIN) rgb[0] = rgb[1] = rgb[2] = 0.0f; else { const float q = hsl[2] < 0.5f ? hsl[2] * (1.0f + hsl[1]) : hsl[2] + hsl[1] - hsl[2] * hsl[1]; const float p = 2.0f * hsl[2] - q; float t[] = {hsl[0] + 2.0f, hsl[0], hsl[0] - 2.0f}; for(int i=0; i<3; ++i) { if(t[i] < 0.0f) t[i] += 6.0f; else if(t[i] > 6.0f) t[i] -= 6.0f; if(t[i] < 1.0f) rgb[i] = p + (q - p) * t[i]; else if(t[i] < 3.0f) rgb[i] = q; else if(t[i] < 4.0f) rgb[i] = p + (q - p) * (4.0f - t[i]); else rgb[i] = p; } } }