/**
* 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 na 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];}
Uwielbiam to, jak komentarze mówią mi o zakresie zmiennych i czego się spodziewać jako dane wyjściowe. Tak porządnie. Dzięki!
Gleno
9
Próbuję użyć tego w projekcie, ale moje wyniki pojawiają się tylko w skali szarości. Czy to jest ograniczenie HSL <-> RGB? Artykuł na Wikipedii wydaje się sugerować, że tylko jedna wartość jest ustawiona dla wszystkich 3 kanałów.
Bill
10
Zwracam uwagę, że użycie Math.roundwprowadza niewielkie niedokładności na dolnych i górnych krańcach (wartości 0 i 255) skali. Wartości, które nie znajdują się na końcach zakresu, można zaokrąglić w górę lub w dół, aby osiągnąć swoją wartość, ale wartości można zaokrąglić tylko w dół do 0 lub do 255. Oznacza to, że zakres wartości odwzorowanych na 0 i 255 jest dokładnie połowa z nich dla innych wartości. Aby rozwiązać ten problem, należy użyć tej formuły zamiast: min(floor(val*256),255). To sprawia, że mapowanie jest prawie idealne.
marcus erronius
13
Ponadto, jeśli otrzymujesz wartości w skali szarości, prawdopodobnie jest to spowodowane liniami używającymi h + 1/3i h - 1/3. W wielu językach używa się dzielenia liczb całkowitych, gdzie 1/3jest zero. aby uzyskać poprawne wyniki, użyj zamiast tego literałów float, np h + 1.0/3.0. : .
Nie mogę uwierzyć, że w Pythonie jest taki standardowy moduł! To naprawdę mnie ratuje. Walczyłem z algorytmem konwersji we wpisie HSL Wikipedii przez 2 godziny. Wydaje się, że algorytm nie może uzyskać prawidłowego wyniku.
Używam brythona, aby uzyskać próbnik kolorów w przeglądarce, właśnie tego potrzebowałem!
EvertW
23
Implementacja kodu Mohsena w języku Java
Zauważ, że wszystkie liczby całkowite są zadeklarowane jako zmiennoprzecinkowe (tj. 1f) i muszą być zmiennoprzecinkowe, w przeciwnym razie wybierzesz kolory szare.
HSL na 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 na 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;}
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
Uważam, że jest to źródło niektórych innych odpowiedzi tutaj.
Oto kod z odpowiedzi Mohsena w C #, jeśli ktoś inny tego chce. Uwaga: Colorto klasa niestandardowa iVector4 pochodzi z OpenTK. Oba można łatwo zastąpić innym wybranym przez siebie.
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);}
Dane wejściowe: kolor szesnastkowy w formacie: [#] 0f4 lub [#] 00ff44 (opcjonalnie znak funta)
Wyjście: HSL w stopniach, procentach, procentach
/**
* 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 na HSL
Wejście: RGB w zakresie 0-255 Wyjście: HSL w stopniach, procentach, procentach.
/**
*
*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 (zakres 0-1) na stopnie, procent, format procentowy
W przypadku obliczeń matematycznych HSL jest łatwiejszy w obsłudze w zakresie 0-1, ale dla czytelności dla człowieka jest łatwiejszy w stopniach, procentach, procentach. Ta funkcja przyjmuje HSL w zakresach 0-1 i zwraca HSL w stopniach, procentach, procentach.
/**
* 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 (stopnie, procent, format procentowy) do HSL w zakresie 0-1
Ta funkcja konwertuje HSL w formacie stopnie, procenty, procenty na zakresy 0–1, aby ułatwić obliczenia.
/**
* 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 na RGB
Wejście: HSL w formacie stopnie, procent, procent Wyjście: RGB w formacie 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;}
Odcień do RGB
Ta funkcja jest wywoływana przez hslToRgb w celu konwersji odcienia na oddzielne wartości 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 na Hex
Dane wejściowe: HSL w formacie stopnie, procent, procent Wyjście: szesnastkowe w formacie 00ff22 (bez znaku funta).
Konwertuje na RGB, a następnie osobno konwertuje na 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 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;}
Dokonałem edycji rgbToHsl, możesz chcieć zaktualizować swój kod php. W kodzie był / jest błąd. W rgbToHsl () s = maxSub / (2 - maxSub)powinno byćs = maxSub / (2 - maxAdd)
Lex
@Lex Zgodnie z tym i tutaj , mój kod jest poprawny. Myślę, że możesz pomylić plik if l < 0.5z else. Czy mógłbyś wyjaśnić swój sposób myślenia? Dziękujemy za poświęcenie czasu na przesłanie opinii!
Cullub
1
przepraszam, masz rację, ale nadal występuje problem z kolejnością operacji. # 8cd08c do HSL przy użyciu tego kalkulatora, (2 - maxSub) = 1.7333333333333334gdy powinno być tak, jak w przykładzie drugiego łącza ( 2 - max - min ) = 0.6352941176470588. Korzystanie z nich 2 - maxAddzbliżało mnie konsekwentnie do wyników z Photoshopa, więc założyłem, że jest to poprawne.
Lex
Och, ok. Dziękuję za zwrócenie uwagi! Naprawiłem to teraz. Mam nadzieję, że to jest pomocne!
Cullub
Jest to bardzo pomocne, byłem w trakcie konwertowania go do formatu
Lex
6
Oto jak to robię, co jest łatwe do zapamiętania, to myślenie o RGB jako o trzech szprychach na kole, oddalonych od siebie o 120 stopni.
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
Najtrudniejsze jest nasycenie, które jest w skali do średniej z tych trzech.
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
To powinna być akceptowana odpowiedź ... znacznie prostsza i bardziej intuicyjna! Czy potrafisz odwrócić algorytm?
JoelFan
@JoelFan - To jest proste, ale niepoprawne . Nie ma żadnego sposobu na czystych wyrażeń wymiernych (z tylko +, -, *, i /) - jak są wykorzystywane przez definicji konwersji kolorów - aby wyrazić je za pomocą tych sinefunkcji o tej samej niezależne (wejście) zmiennych. Mimo to dobrze jest zrozumieć zasadę (ale nie wykonywać konwersji).
MarianD
Problem z tym rozwiązaniem polega na tym, że ŚREDNIA jest zawsze równa ZERO: (R1 + G1 + B1) = L*[ SIN(H) + SIN(H+120) + SIN(H+240) ]- i teraz, jeśli użyjemy wzoru sin(a)+sin(b) = 2*sin((a+b)/2)*cos((a-b)/2)na pierwsze dwa grzechy, otrzymamy: AVERAGE=L*( sin(h+60) + sin(h+240) )i znowu AVERAGE= L*2*sin(h+150)*cos(-180/2) = 0(ponieważ cos (-180/2) = cos (90) = 0). Więc obliczenie nasycenia jest błędne iw rzeczywistości nasycenie działa tutaj jako luminancja.
Kamil Kiełczewski
@JoelFan Drugi problem z tym rozwiązaniem polega na tym, że musimy dodać 180 stopni do H, aby mieć "kompatybilną" wersję z en.wikipedia.org/wiki/HSL_and_HSV#Converting_to_RGB (przypadek testowy: czerwony kolor dla H = 0), ale także nadal występuje problem z liczbą kolorów - w powyższym rozwiązaniu kolory żółty, magenta i cyjan są pomijane i / lub odwzorowywane w niewłaściwy sposób. Jest js skrzypce z porównaniem: jsfiddle.net/Lamik/9s24uc1o/10
Kamil Kiełczewski
3
Oto szybka, super prosta, bezgałęziowa wersja w GLSL:
Oto zmodyfikowana funkcja javascript, która wyświetla Hue w ustawionych 0-360 stopniach.
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));
Mam to od HSL Picker Brandona Mathisa kodu źródłowego .
Pierwotnie został napisany w CoffeeScript . Przekonwertowałem go na JavaScript za pomocą konwertera online i wyjąłem mechanizm, aby sprawdzić, czy dane wejściowe użytkownika były prawidłową wartością RGB. Ta odpowiedź zadziałała w moim przypadku, ponieważ najbardziej pozytywna odpowiedź w tym poście, którą stwierdziłem, nie daje prawidłowej wartości HSL.
Zwróć uwagę, że zwraca hslawartość areprezentującą krycie / przezroczystość. 0jest całkowicie przezroczysty i 1całkowicie kryjący.
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];}
Użyłem tego jako podstawy dla metody Pythona. Dzięki.
JayJay123,
to nie jest HSL na RGB, jak prosi plakat
bryc
1
Gdy zamiast tego potrzebujesz RGB do HSV i odwrotnie:
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)];}
Oto kod z odpowiedzi Mohsena w C # skierowany specjalnie dla Unity3D. Został on zaadaptowany z odpowiedzi C # udzielonej przez Aleca Thileniusa powyżej.
usingUnityEngine;usingSystem.Collections;publicclassColorTools{/// <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>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(r, g, b, hsl.w);}// 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;}/// <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>publicstaticVector4RgbaToHsl(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);elseif(rgba.g > rgba.b)
h =(rgba.b - rgba.r)/ d +2.0f;else
h =(rgba.r - rgba.g)/ d +4.0f;
h /=6.0f;}returnnewVector4(h, s, l, rgba.a);}}
Dla wszystkich, którzy powiedzieli, że rozwiązanie Garry Tan konwertuje nieprawidłowo z RGB na HSL iz powrotem. To dlatego, że w swoim kodzie pominął ułamkową część liczby. Poprawiłem jego kod (javascript). Przepraszam za link w języku rosyjskim, ale brak na angielskim - 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)}};};
Wartość hsl | a koloru, ustawiona w javascript, zostanie natychmiast przekonwertowana na rgb | a Wszystko, co musisz zrobić, to uzyskać dostęp do obliczonej wartości stylu
Technicznie rzecz biorąc, myślę, że to nie jest jeszcze jakikolwiek wiersze kodu - jest to po prostu wykonywane automatycznie. Tak więc, w zależności od środowiska, może ci się to udać. Nie chodzi o to, że nie ma tu wielu bardzo przemyślanych odpowiedzi. Nie wiem, jaki jest twój cel.
A co jeśli chcesz przekonwertować z rbg | a na hsl | a?
Implementacja C ++ z prawdopodobnie lepszą wydajnością niż kod @Mohsen. Używa zakresu [0-6] dla odcienia, unikając dzielenia i mnożenia przez 6. Zakres S i L wynosi [0,1]
Please.HEX_to_HSV('#ffeb3b')
Odpowiedzi:
Garry Tan zamieścił na swoim blogu rozwiązanie Javascript (które przypisuje nieistniejącemu już mjijackson.com, ale jest zarchiwizowane tutaj, a oryginalny autor ma streszczenie - dzięki user2441511).
Kod został ponownie opublikowany poniżej:
HSL na RGB:
RGB na HSL:
źródło
Math.round
wprowadza niewielkie niedokładności na dolnych i górnych krańcach (wartości 0 i 255) skali. Wartości, które nie znajdują się na końcach zakresu, można zaokrąglić w górę lub w dół, aby osiągnąć swoją wartość, ale wartości można zaokrąglić tylko w dół do 0 lub do 255. Oznacza to, że zakres wartości odwzorowanych na 0 i 255 jest dokładnie połowa z nich dla innych wartości. Aby rozwiązać ten problem, należy użyć tej formuły zamiast:min(floor(val*256),255)
. To sprawia, że mapowanie jest prawie idealne.h + 1/3
ih - 1/3
. W wielu językach używa się dzielenia liczb całkowitych, gdzie1/3
jest zero. aby uzyskać poprawne wyniki, użyj zamiast tego literałów float, nph + 1.0/3.0
. : .Najłatwiejszy sposób, python na ratunek : D
źródło
Color::HSL.new(40,50,60).to_rgb
Implementacja kodu Mohsena w języku Java
Zauważ, że wszystkie liczby całkowite są zadeklarowane jako zmiennoprzecinkowe (tj. 1f) i muszą być zmiennoprzecinkowe, w przeciwnym razie wybierzesz kolory szare.
HSL na RGB
RGB na HSL
źródło
Artykuł dotyczący HSL i HSV na Wikipedii zawiera kilka formuł. Obliczenia są nieco skomplikowane, więc warto przyjrzeć się istniejącym implementacjom .
źródło
Jeśli szukasz czegoś, co zdecydowanie jest zgodne z semantyką CSS dla HSL i RGB, możesz użyć algorytmu określonego w specyfikacji CSS 3 , który brzmi:
Uważam, że jest to źródło niektórych innych odpowiedzi tutaj.
źródło
Kod C # z odpowiedzi Mohsena.
Oto kod z odpowiedzi Mohsena w C #, jeśli ktoś inny tego chce. Uwaga:
Color
to klasa niestandardowa iVector4
pochodzi z OpenTK. Oba można łatwo zastąpić innym wybranym przez siebie.Hsl To Rgba
Rgba To Hsl
źródło
Implementacja php kodu C # Chrisa
Również stąd , co bardzo dobrze wyjaśnia matematykę.
Jest to w zasadzie zestaw funkcji do konwersji do iz HSL (jasność nasycenia odcienia)
Testowane i działające na PHP 5.6.15
TL; DR : Pełny kod można znaleźć tutaj w Pastebin .
Hex do HSL
Dane wejściowe: kolor szesnastkowy w formacie: [#] 0f4 lub [#] 00ff44 (opcjonalnie znak funta)
Wyjście: HSL w stopniach, procentach, procentach
RGB na HSL
Wejście: RGB w zakresie 0-255 Wyjście: HSL w stopniach, procentach, procentach.
HSL (zakres 0-1) na stopnie, procent, format procentowy
W przypadku obliczeń matematycznych HSL jest łatwiejszy w obsłudze w zakresie 0-1, ale dla czytelności dla człowieka jest łatwiejszy w stopniach, procentach, procentach. Ta funkcja przyjmuje HSL w zakresach 0-1 i zwraca HSL w stopniach, procentach, procentach.
HSL (stopnie, procent, format procentowy) do HSL w zakresie 0-1
Ta funkcja konwertuje HSL w formacie stopnie, procenty, procenty na zakresy 0–1, aby ułatwić obliczenia.
HSL na RGB
Wejście: HSL w formacie stopnie, procent, procent Wyjście: RGB w formacie
255, 255, 255
.Odcień do RGB
Ta funkcja jest wywoływana przez hslToRgb w celu konwersji odcienia na oddzielne wartości RGB.
HSL na Hex
Dane wejściowe: HSL w formacie stopnie, procent, procent Wyjście: szesnastkowe w formacie
00ff22
(bez znaku funta).Konwertuje na RGB, a następnie osobno konwertuje na hex.
źródło
rgbToHsl
, możesz chcieć zaktualizować swój kod php. W kodzie był / jest błąd. W rgbToHsl ()s = maxSub / (2 - maxSub)
powinno byćs = maxSub / (2 - maxAdd)
if l < 0.5
zelse
. Czy mógłbyś wyjaśnić swój sposób myślenia? Dziękujemy za poświęcenie czasu na przesłanie opinii!(2 - maxSub) = 1.7333333333333334
gdy powinno być tak, jak w przykładzie drugiego łącza( 2 - max - min ) = 0.6352941176470588
. Korzystanie z nich2 - maxAdd
zbliżało mnie konsekwentnie do wyników z Photoshopa, więc założyłem, że jest to poprawne.Oto jak to robię, co jest łatwe do zapamiętania, to myślenie o RGB jako o trzech szprychach na kole, oddalonych od siebie o 120 stopni.
Najtrudniejsze jest nasycenie, które jest w skali do średniej z tych trzech.
źródło
+
,-
,*
, i/
) - jak są wykorzystywane przez definicji konwersji kolorów - aby wyrazić je za pomocą tychsine
funkcji o tej samej niezależne (wejście) zmiennych. Mimo to dobrze jest zrozumieć zasadę (ale nie wykonywać konwersji).(R1 + G1 + B1) = L*[ SIN(H) + SIN(H+120) + SIN(H+240) ]
- i teraz, jeśli użyjemy wzorusin(a)+sin(b) = 2*sin((a+b)/2)*cos((a-b)/2)
na pierwsze dwa grzechy, otrzymamy:AVERAGE=L*( sin(h+60) + sin(h+240) )
i znowuAVERAGE= L*2*sin(h+150)*cos(-180/2) = 0
(ponieważ cos (-180/2) = cos (90) = 0). Więc obliczenie nasycenia jest błędne iw rzeczywistości nasycenie działa tutaj jako luminancja.Oto szybka, super prosta, bezgałęziowa wersja w GLSL:
Nie robi się dużo krócej niż to ~
Link do oryginalnego proof-of-concept: https://www.shadertoy.com/view/XljGzV
(Zastrzeżenie: to nie mój kod!)
źródło
Oto zmodyfikowana funkcja javascript, która wyświetla Hue w ustawionych 0-360 stopniach.
źródło
Mam to od HSL Picker Brandona Mathisa kodu źródłowego .
Pierwotnie został napisany w CoffeeScript . Przekonwertowałem go na JavaScript za pomocą konwertera online i wyjąłem mechanizm, aby sprawdzić, czy dane wejściowe użytkownika były prawidłową wartością RGB. Ta odpowiedź zadziałała w moim przypadku, ponieważ najbardziej pozytywna odpowiedź w tym poście, którą stwierdziłem, nie daje prawidłowej wartości HSL.
Zwróć uwagę, że zwraca
hsla
wartośća
reprezentującą krycie / przezroczystość.0
jest całkowicie przezroczysty i1
całkowicie kryjący.źródło
Gdy zamiast tego potrzebujesz RGB do HSV i odwrotnie:
źródło
Kod Unity3D C # z odpowiedzi Mohsena.
Oto kod z odpowiedzi Mohsena w C # skierowany specjalnie dla Unity3D. Został on zaadaptowany z odpowiedzi C # udzielonej przez Aleca Thileniusa powyżej.
źródło
Dla wszystkich, którzy powiedzieli, że rozwiązanie Garry Tan konwertuje nieprawidłowo z RGB na HSL iz powrotem. To dlatego, że w swoim kodzie pominął ułamkową część liczby. Poprawiłem jego kod (javascript). Przepraszam za link w języku rosyjskim, ale brak na angielskim - HSL-wiki
źródło
Wartość hsl | a koloru, ustawiona w javascript, zostanie natychmiast przekonwertowana na rgb | a Wszystko, co musisz zrobić, to uzyskać dostęp do obliczonej wartości stylu
Technicznie rzecz biorąc, myślę, że to nie jest jeszcze jakikolwiek wiersze kodu - jest to po prostu wykonywane automatycznie. Tak więc, w zależności od środowiska, może ci się to udać. Nie chodzi o to, że nie ma tu wielu bardzo przemyślanych odpowiedzi. Nie wiem, jaki jest twój cel.
A co jeśli chcesz przekonwertować z rbg | a na hsl | a?
źródło
Implementacja C ++ z prawdopodobnie lepszą wydajnością niż kod @Mohsen. Używa zakresu [0-6] dla odcienia, unikając dzielenia i mnożenia przez 6. Zakres S i L wynosi [0,1]
źródło
Z H, S i L w zakresie [0,1]:
źródło
Potrzebowałem naprawdę lekkiego, to nie jest w 100%, ale zbliża się wystarczająco do niektórych zastosowań.
źródło
Implementacja PHP kodu @ Mohsen (w tym Test!)
Przepraszamy za ponowne przesłanie tego. Ale naprawdę nie widziałem żadnej innej implementacji, która zapewniałaby jakość, której potrzebowałem.
źródło