/**
* 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];}
Мне нравится, как комментарии говорят мне диапазон переменных и что ожидать в качестве результата. Так аккуратно. Спасибо!
Глено
9
Я пытаюсь использовать это для проекта, но мои результаты только отображаются в градациях серого. Это ограничение HSL <-> RGB? Статья в Википедии, кажется, предполагает, что для всех 3 каналов установлено только одно значение.
Билл
10
Я хотел бы отметить, что использование Math.roundвносит небольшие неточности на нижнем и верхнем уровнях (значения 0 и 255) шкалы. Значения, которые не находятся на концах диапазона, могут округляться либо вверх, либо вниз, чтобы достичь их значения, но значения можно округлять только до 0 или до 255. Это означает, что диапазон значений, который отображается в 0 и 255, точно половина из них для других ценностей. Чтобы исправить это, используйте эту формулу вместо: min(floor(val*256),255). Это делает отображение почти идеальным.
Маркус Эррониус
13
Кроме того, если вы получаете значения в градациях серого, это, вероятно, из-за строк, которые используют h + 1/3и h - 1/3. Во многих языках это использует целочисленное деление, где 1/3ноль. чтобы получить правильные результаты, использование поплавка литералов вместо этого, т.е. .: h + 1.0/3.0.
Я не могу поверить, что в Python есть такой стандартный модуль! Это действительно спасает меня. Я боролся с алгоритмом преобразования в записи HSL Википедии в течение 2 часов. Кажется, что алгоритм не может получить правильный вывод.
Я использую brython, чтобы получить палитру цветов в браузере, это как раз то, что мне нужно!
EvertW
23
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
*/publicstaticint[] 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 ={to255(r), to255(g), to255(b)};return rgb;}publicstaticint to255(float v){return(int)Math.min(255,256*v);}/** Helper method that converts hue to rgb */publicstaticfloat 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
*/publicstaticfloat[] 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);elseif(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;}
Если вы ищете что-то, что определенно соответствует семантике 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
Я считаю, что это источник некоторых других ответов здесь.
Вот код ответа Мохсена на C #, если кто-то еще этого хочет. Примечание: Colorэто пользовательский класс Vector4из OpenTK. Оба легко заменить на что-то другое по вашему выбору.
Hsl To 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>publicstaticColorHslToRgba(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);}returnnewColor((int)(r *255),(int)(g *255),(int)(b *255),(int)(hsl.W *255));}// Helper for HslToRgbaprivatestaticfloatHueToRgb(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>publicstaticVector4RgbaToHsl(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);elseif(g > b)
h =(b - r)/ d +2.0f;else
h =(r - g)/ d +4.0f;
h /=6.0f;}returnnewVector4(h, s, l, rgba.A /255.0f);}
Входные данные: шестнадцатеричный цвет в формате: [#] 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{returnfalse;}
$r = hexdec($r);
$g = hexdec($g);
$b = hexdec($b);
$hsl = rgbToHsl($r,$g,$b);return $hsl;}
RGB в HSL
Вход: RGB в диапазоне 0-255 Выход: HSL в градусах, процентах, процентах.
/**
*
*Credits:
* /programming/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 hueswitch($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;}
Оттенок к 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;}
Конвертирует в RGB, затем конвертирует отдельно в гекс.
/**
* 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 formatreturnfalse;}}if(strlen($hexG)!=2){if(strlen($hexG)==1){
$hexG ="0". $hexG;}else{returnfalse;}}if(strlen($hexB)!=2){if(strlen($hexB)==1){
$hexB ="0". $hexB;}else{returnfalse;}}//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;}
Я сделал правку rgbToHsl , вы можете обновить свой php-код. В коде была / есть ошибка. В rgbToHsl () s = maxSub / (2 - maxSub)должно бытьs = maxSub / (2 - maxAdd)
Lex
@Lex Согласно здесь и здесь , мой код на самом деле правильный. Я думаю, что вы можете спутать if l < 0.5с else. Не могли бы вы объяснить свое мышление? Спасибо, что нашли время, чтобы дать отзыв, хотя!
Cullub
1
извините, вы правы, но все еще есть проблема порядка операций. # 8cd08c для HSL, используя этот calc, (2 - maxSub) = 1.7333333333333334когда он должен быть как во втором примере ссылки( 2 - max - min ) = 0.6352941176470588 . Использование 2 - maxAddзаставило меня постоянно приближаться к выходу фотошопов, поэтому я предположил, что это правильно.
Lex
О хорошо Спасибо что подметил это! Я исправил это сейчас. Надеюсь, это полезно!
Это должен быть принятый ответ ... гораздо проще и понятнее! Можете ли вы изменить алгоритм?
JoelFan
@JoelFan - это просто, но не правильно . Там нет никакого способа для чисто рациональных выражений (только с+ , -, *и /) - также используются определения для преобразования цветов - выразить их с помощью sineфункций с одинаковым независимо (вход) переменных. Несмотря на это, это хорошо для понимания принципа (но не для выполнения преобразований).
MarianD
Проблема с этим решением состоит в том, что AVERAGE всегда равен нулю: (R1 + G1 + B1) = L*[ SIN(H) + SIN(H+120) + SIN(H+240) ]- и теперь, если мы используем формулу sin(a)+sin(b) = 2*sin((a+b)/2)*cos((a-b)/2)для первых двух грехов, мы получаем: AVERAGE=L*( sin(h+60) + sin(h+240) )и снова AVERAGE= L*2*sin(h+150)*cos(-180/2) = 0(так как cos (-180/2) = cos (90) = 0). Таким образом, расчет насыщенности неверен и фактически насыщенность здесь работает как яркость.
Камиль Келчевски
@JoelFan Вторая проблема, связанная с этим решением, заключается в том, что нам нужно добавить 180 градусов к Н, чтобы иметь «совместимую» версию с en.wikipedia.org/wiki/HSL_and_HSV#Converting_to_RGB (контрольный пример: красный цвет для H = 0), но также и для него. все еще проблема с количеством цветов - в приведенном выше решении желтый, пурпурный и голубой цвета пропускаются и / или отображаются неправильно. Есть js скрипка для сравнения: jsfiddle.net/Lamik/9s24uc1o/10
Камил Келчевски
3
Вот быстрая, супер-простая версия без ответвлений в GLSL:
Вот модифицированная функция javascript, она выводит Hue в диапазоне 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));
Я получил это от HSL Picker Брэндона Матиса исходного кода .
Первоначально он был написан на CoffeeScript . Я преобразовал его в JavaScript, используя онлайн-конвертер, и вынул механизм, чтобы убедиться, что пользовательский ввод является допустимым значением RGB. Этот ответ сработал для моего варианта использования, поскольку я обнаружил, что ответ с наибольшим количеством голосов в этом посте не дает действительного значения 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];}
Я использовал это в качестве основы для метода Python. Спасибо.
JayJay123
это не HSL к RGB, поскольку плакат просит
bryc
1
Когда вам нужен 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)){case0:
r = max;
g = med;
b = min;break;case1:
r = med;
g = max;
b = min;break;case2:
r = min;
g = max;
b = med;break;case3:
r = min;
g = med;
b = max;break;case4:
r = med;
g = min;
b = max;break;case5:
r = max;
g = min;
b = med;break;}return[Math.round(r *255),Math.round(g *255),Math.round(b *255)];}
Для всех, кто сказал, что решение Garry Tan некорректно конвертируется из 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 ;}elseif(max == r && g < b){
h =1.0472*(g - b)/ d +6.2832;}elseif(max == g){
h =1.0472*(b - r)/ d +2.0944;}elseif(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 | значение цвета, установленное в javascript, будет немедленно преобразовано в rgb | a. Все, что вам нужно сделать, это получить доступ к вычисленному значению стиля.
Технически, я думаю, это даже не какой - либо строки кода - это просто делается автоматически. Таким образом, в зависимости от вашей среды, вы можете сойти с рук только с этим. Не то, чтобы здесь не было много очень вдумчивых ответов. Я не знаю, какова ваша цель.
А что если вы хотите конвертировать из rbg | a в hsl | a?
Реализация на C ++, возможно, с лучшей производительностью, чем код @Mohsen. Он использует диапазон [0-6] для оттенка, избегая деления и умножения на 6. Диапазон S и L равен [0,1]
Please.HEX_to_HSV('#ffeb3b')
Ответы:
Гарри Тан опубликовал в своем блоге решение Javascript (которое он приписывает уже не существующему mjijackson.com, но здесь он заархивирован, и у первоначального автора есть суть - спасибо пользователю 2441511).
Код повторно опубликован ниже:
HSL в RGB:
RGB в HSL:
источник
Math.round
вносит небольшие неточности на нижнем и верхнем уровнях (значения 0 и 255) шкалы. Значения, которые не находятся на концах диапазона, могут округляться либо вверх, либо вниз, чтобы достичь их значения, но значения можно округлять только до 0 или до 255. Это означает, что диапазон значений, который отображается в 0 и 255, точно половина из них для других ценностей. Чтобы исправить это, используйте эту формулу вместо:min(floor(val*256),255)
. Это делает отображение почти идеальным.h + 1/3
иh - 1/3
. Во многих языках это использует целочисленное деление, где1/3
ноль. чтобы получить правильные результаты, использование поплавка литералов вместо этого, т.е. .:h + 1.0/3.0
.Нашел самый простой способ, спасти питона : D
источник
Color::HSL.new(40,50,60).to_rgb
Java-реализация кода Мохсена
Обратите внимание, что все целые числа объявлены как float (то есть 1f) и должны быть float, в противном случае вы получите серый цвет.
HSL в RGB
RGB в HSL
источник
Статья для HSL и HSV в Википедии содержит некоторые формулы. Расчеты немного сложны, поэтому может быть полезно взглянуть на существующие реализации .
источник
Если вы ищете что-то, что определенно соответствует семантике CSS для HSL и RGB, вы можете использовать алгоритм, указанный в спецификации CSS 3 , которая гласит:
Я считаю, что это источник некоторых других ответов здесь.
источник
Код C # из ответа Мохсена.
Вот код ответа Мохсена на C #, если кто-то еще этого хочет. Примечание:
Color
это пользовательский классVector4
из OpenTK. Оба легко заменить на что-то другое по вашему выбору.Hsl To Rgba
Rgba To Hsl
источник
Реализация PHP- кода C # Криса
Также отсюда , что очень хорошо объясняет это.
Это в основном набор функций для преобразования в и из HSL (Hue Saturation Lightness)
Протестировано и работает на PHP 5.6.15
TL; DR : Полный код можно найти здесь, на Pastebin .
Hex в HSL
Входные данные: шестнадцатеричный цвет в формате: [#] 0f4 или [#] 00ff44 (знак фунта необязательно).
Выходные данные: HSL в градусах, процентах, процентах
RGB в HSL
Вход: RGB в диапазоне 0-255 Выход: HSL в градусах, процентах, процентах.
HSL (диапазон 0-1) в градусы, проценты, проценты
В математических вычислениях с HSL легче работать в диапазоне 0-1, но для удобства чтения легче в градусах, процентах, процентах. Эта функция принимает HSL в диапазонах 0-1 и возвращает HSL в градусах, процентах, процентах.
HSL (градусы, проценты, проценты) до HSL в диапазоне 0-1
Эта функция преобразует HSL в формате градусы, проценты, проценты в диапазоны 0-1 для облегчения вычислений.
HSL в RGB
Вход: HSL в формате Градусы, Проценты, Процент Вывод: RGB в формате
255, 255, 255
.Оттенок к RGB
Эта функция вызывается hslToRgb для преобразования оттенка в отдельные значения RGB.
HSL в Hex
Вход: HSL в формате градусы, проценты, процент Выход: шестнадцатеричный формат
00ff22
(без знака фунта).Конвертирует в RGB, затем конвертирует отдельно в гекс.
источник
rgbToHsl
, вы можете обновить свой php-код. В коде была / есть ошибка. В rgbToHsl ()s = maxSub / (2 - maxSub)
должно бытьs = maxSub / (2 - maxAdd)
if l < 0.5
сelse
. Не могли бы вы объяснить свое мышление? Спасибо, что нашли время, чтобы дать отзыв, хотя!(2 - maxSub) = 1.7333333333333334
когда он должен быть как во втором примере ссылки( 2 - max - min ) = 0.6352941176470588
. Использование2 - maxAdd
заставило меня постоянно приближаться к выходу фотошопов, поэтому я предположил, что это правильно.Это то, как я это делаю, и это легко запомнить - думать о RGB как о трех спицах на колесе, разнесенных на 120 градусов.
Сложная часть - это насыщенность, которая в масштабе до среднего из этих трех.
источник
+
,-
,*
и/
) - также используются определения для преобразования цветов - выразить их с помощьюsine
функций с одинаковым независимо (вход) переменных. Несмотря на это, это хорошо для понимания принципа (но не для выполнения преобразований).(R1 + G1 + B1) = L*[ SIN(H) + SIN(H+120) + SIN(H+240) ]
- и теперь, если мы используем формулуsin(a)+sin(b) = 2*sin((a+b)/2)*cos((a-b)/2)
для первых двух грехов, мы получаем:AVERAGE=L*( sin(h+60) + sin(h+240) )
и сноваAVERAGE= L*2*sin(h+150)*cos(-180/2) = 0
(так как cos (-180/2) = cos (90) = 0). Таким образом, расчет насыщенности неверен и фактически насыщенность здесь работает как яркость.Вот быстрая, супер-простая версия без ответвлений в GLSL:
Не становится намного короче этого ~
Ссылка на оригинальное подтверждение концепции: https://www.shadertoy.com/view/XljGzV
(Отказ от ответственности: не мой код!)
источник
Вот модифицированная функция javascript, она выводит Hue в диапазоне 0-360 градусов.
источник
Я получил это от HSL Picker Брэндона Матиса исходного кода .
Первоначально он был написан на CoffeeScript . Я преобразовал его в JavaScript, используя онлайн-конвертер, и вынул механизм, чтобы убедиться, что пользовательский ввод является допустимым значением RGB. Этот ответ сработал для моего варианта использования, поскольку я обнаружил, что ответ с наибольшим количеством голосов в этом посте не дает действительного значения HSL.
Обратите внимание, что он возвращает
hsla
значение сa
представлением непрозрачности / прозрачности.0
является полностью прозрачным и1
полностью непрозрачным.источник
Когда вам нужен RGB для HSV и наоборот:
источник
Unity3D C # Код из ответа Мохсена.
Вот код ответа Мохсена в C #, предназначенный специально для Unity3D. Он был адаптирован из ответа C #, данного Алеком Тилениусом выше.
источник
Для всех, кто сказал, что решение Garry Tan некорректно конвертируется из RGB в HSL и обратно. Это потому, что он пропустил часть числа в своем коде. Я исправил его код (javascript). Извините за ссылку на русском языке, но на английском отсутствует - HSL-wiki
источник
Hsl | значение цвета, установленное в javascript, будет немедленно преобразовано в rgb | a. Все, что вам нужно сделать, это получить доступ к вычисленному значению стиля.
Технически, я думаю, это даже не какой - либо строки кода - это просто делается автоматически. Таким образом, в зависимости от вашей среды, вы можете сойти с рук только с этим. Не то, чтобы здесь не было много очень вдумчивых ответов. Я не знаю, какова ваша цель.
А что если вы хотите конвертировать из rbg | a в hsl | a?
источник
Реализация на C ++, возможно, с лучшей производительностью, чем код @Mohsen. Он использует диапазон [0-6] для оттенка, избегая деления и умножения на 6. Диапазон S и L равен [0,1]
источник
С H, S и L в диапазоне [0,1]:
источник
Мне нужен действительно легкий вес, его не 100%, но он подходит достаточно близко для некоторых случаев использования.
источник
PHP-реализация кода @ Мохсена (включая Test!)
Извините, что опубликовал это. Но я действительно не видел никакой другой реализации, которая давала бы мне необходимое качество.
источник