19 ответов:
Гарри Тан опубликовал решение Javascript на блог (который он приписывает теперь несуществующему mjijackson.com,но архивируется здесь и у оригинального автора есть суть - благодаря user2441511).
код повторно размещен ниже:
HSL в 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 в 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]; }
нашел самый простой способ, python к спасение: D
colorsys.hls_to_rgb(h, l, s)преобразование цвета из координат HLS в координаты RGB.
статьи HSL и HSV в Википедии содержит некоторые формулы. Расчеты немного сложнее, поэтому может быть полезно взглянуть на существующими реализациями.
Если вы ищете что-то, что определенно соответствует семантике CSS для HSL и RGB, вы можете использовать алгоритм, указанный в спецификации CSS 3, который гласит:
HOW TO RETURN hsl.to.rgb(h, s, l): SELECT: l<=0.5: PUT l*(s+1) IN m2 ELSE: PUT l+s-l*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Я считаю, что это источник для некоторых других ответов здесь.
Java реализация кода Мохсена
обратите внимание, что все целые числа объявляются как float (т. е. 1f) и должны быть float, иначе вы будете выбирать серые цвета.
HSL в 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 в 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#, если кто-то еще этого хочет. Примечание:
Color- это пользовательский класс иVector4из OpenTK. Оба легко заменить на что-то другое по вашему выбору.Hsl В Rgba
/// <summary> /// 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] ) /// </summary> /// <param name="hsl">Vector4 defining X = h, Y = s, Z = l, W = a. Ranges [0, 1.0]</param> /// <returns>RGBA Color. Ranges [0, 255]</returns> 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 To Hsl
/// <summary> /// 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] ) /// </summary> /// <param name="rgba"></param> /// <returns></returns> 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); }
реализация на PHP C# код Криса
и с здесь, что очень хорошо объясняет математику.
это в основном куча функций для преобразования В и из HSL (Hue Saturation Lightness)
протестировано и работает на PHP 5.6.15
TL; DR: полный код можно найти здесь на Pastebin.
Hex to HSL
вход: шестнадцатеричный цвет в формате: [#] 0f4 или [#] 00ff44 (знак фунта необязательно)
Вывод: HSL в градусах, процентах, процентах/** * 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 в HSL
вход: RGB в диапазоне 0-255 Выход: HSL в градусах, процентах, процентах.
/** * *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; }HSL (диапазон 0-1) в градусах, процентах, процентах формат
для математических вычислений HSL легче иметь дело с диапазоном 0-1, но для человеческой читаемости это проще в градусах, Проценты, Проценты. Эта функция принимает HSL в диапазонах 0-1 и возвращает HSL в градусах, процентах, процентах.
/** * 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 (Градусы, проценты, процентный формат) в HSL в диапазоне 0-1
эта функция преобразует HSL в формате градусов, процентов, процентов, в диапазоны 0-1 для упрощения вычислений.
/** * 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 в RGB
вход: HSL в формате градусов, процентов, процентов Вывод: RGB в формате
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 to RGB
эта функция вызывается hslToRgb для преобразования оттенка в отдельные значения RGB.
/** * 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 to Hex
вход: HSL в градусах формата, процентах, процентах Вывод: Hex в формате
00ff22(не подписать фунт).преобразует в RGB, а затем преобразует отдельно в hex.
/** * 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; }
вот как я это делаю, что легко запомнить, это думать о RGB как о трех спицах на колесе, 120 градусов друг от друга.
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сложная часть-это насыщение, которое в масштабе до среднего из этих трех.
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
здесь Быстрый, супер-простой, дистанционный вариант в GLSL:
vec3 hsl2rgb( vec3 c ) { vec3 rgb = clamp(abs(mod(c.x*6.0 + vec3(0.0, 4.0, 2.0), 6.0)-3.0)-1.0, 0.0, 1.0); return c.z + c.y * (rgb-0.5)*(1.0-abs(2.0*c.z-1.0)); }не становится намного меньше, чем ~
ссылка на исходное доказательство концепции:https://www.shadertoy.com/view/XljGzV
(отказ от ответственности: не мой код!)
вот модифицированная функция javascript, она выводит оттенок в наборе 0-360 градусов.
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));
Unity3D C# код из ответа Мохсена.
вот код из ответа Мохсен в C# и предназначенные специально для Unity3D. Он был адаптирован из C# ответила выше Алека Thilenius.
using UnityEngine; using System.Collections; public class ColorTools { /// <summary> /// 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] ) /// </summary> /// <param name="hsl">Vector4 defining X = h, Y = s, Z = l, W = a. Ranges [0, 1.0]</param> /// <returns>RGBA Color. Ranges [0.0, 1.0]</returns> 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; } /// <summary> /// 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] ) /// </summary> /// <param name="rgba"></param> /// <returns></returns> 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); } }
для всех, кто сказал, что Гарри Тан решение преобразования неправильно из RGB в HSL и обратно. Это потому, что он пропустил дробную часть числа в своем коде. Я исправил его код (javascript). Извините за ссылку на русском языке, но на английском отсутствует -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) } }; };
я получил это от Брэндона Матиса HSL Picker исходный код.
Он был первоначально написано в CoffeeScript. Я преобразовал его в JavaScript с помощью онлайн-конвертера и достал механизм для проверки того, что пользовательский ввод был допустимым значением RGB. Этот ответ работал для моего usecase, так как самый проголосованный ответ на этот пост я обнаружил, что он не дает действительного значения HSL.
обратите внимание, что он возвращает
hslaзначением, сaпредставляющие непрозрачность/прозрачность.0совершенно прозрачно, и1полностью непрозрачный.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]; }
С H, S и L в диапазоне [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 }; } }
для того, когда вам нужно RGB для HSV и наоборот вместо этого:
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)]; }
Мне нужен был действительно легкий вес, его не 100%, но он достаточно близок для некоторых случаев использования.
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); }
PHP для внедрения кода @Мохсен (в том числе тест!)
извините, чтобы повторно опубликовать это. Но я действительно не видел никакой другой реализации, которая дает качество, в котором я нуждался.
/** * 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 '<div style="background-color:rgb(' .$rgb[0] . ', ' . $rgb[1] . ', ' . $rgb[2] . ');padding:2px;"></div>'; } /* End Test */
значение цвета hsl|a, установленное в javascript, будет мгновенно преобразованный в rgb / a все, что вам нужно сделать, это получить доступ к вычисленное значение стиля
document.body.style.color = 'hsla(44, 100%, 50%, 0.8)'; console.log(window.getComputedStyle(document.body).color); // displays: rgba(255, 187, 0, 0.8)технически, я думаю, это даже не любой строки кода-это просто сделано автоматически. Итак, в зависимости от вашего окружения, вы возможно, это сойдет ему с рук. Не то чтобы их не было здесь много очень продуманных ответов. Я не знаю, что ваш цель.
теперь, что делать, если вы хотите конвертировать из rbg|a в hsl / a?
реализация C++ с, вероятно, лучшей производительностью, чем код @Mohsen. Он использует диапазон [0-6] для оттенка, избегая деления и умножения на 6. Диапазон S и L равен [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; } } }
Comments