Als nicht thematisch markiert, obwohl nach einem Algorithmus gefragt wird, der unter stackoverflow.com/help/on-topic explizit zum Thema gehört - was gibt es?
LeeGee
2
Dies ist die schlechteste Abstimmung, die ich je auf dieser Website gesehen habe, und das sagt viel aus! Ich bin die erste Stimme, die wiedereröffnet wird.
/**
* 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 zu 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];}
Ich finde es toll, wie die Kommentare mir den Bereich der Variablen mitteilen und was mich als Ausgabe erwartet. So ordentlich. Vielen Dank!
Gleno
9
Ich versuche, dies für ein Projekt zu verwenden, aber meine Ergebnisse werden nur in Graustufen angezeigt. Ist dies eine Einschränkung von HSL <-> RGB? Der Wikipedia-Artikel scheint darauf hinzudeuten, dass für alle drei Kanäle nur ein einziger Wert festgelegt ist.
Bill
10
Ich möchte darauf hinweisen, dass die Verwendung Math.roundkleine Ungenauigkeiten am unteren und oberen Ende (Werte von 0 und 255) der Skala mit sich bringt. Werte, die sich nicht an den Enden des Bereichs befinden, können entweder auf- oder abgerundet werden, um ihren Wert zu erreichen. Werte können jedoch nur auf 0 oder bis zu 255 abgerundet werden. Dies bedeutet, dass der Wertebereich, der auf 0 und 255 abgebildet wird, genau ist die Hälfte davon für andere Werte. Verwenden Sie stattdessen diese Formel, um dies zu beheben : min(floor(val*256),255). Dies macht das Mapping nahezu perfekt.
Marcus Eriusius
13
Wenn Sie Graustufenwerte erhalten, liegt dies wahrscheinlich an den Zeilen, die h + 1/3und verwenden h - 1/3. In vielen Sprachen wird die Ganzzahldivision verwendet, wobei 1/3Null ist. Verwenden Sie stattdessen Float-Literale, um korrekte Ergebnisse zu erhalten h + 1.0/3.0.
Ich kann nicht glauben, dass es in Python ein solches Standardmodul gibt! Das rettet mich wirklich. Ich habe 2 Stunden lang mit dem Konvertierungsalgorithmus im HSL-Eintrag von Wikipedia zu kämpfen. Scheint, dass der Algorithmus nicht die richtige Ausgabe erhalten kann.
Ich benutze Brython, um einen Farbwähler im Browser zu bekommen, das ist genau das, was ich brauchte!
EvertW
23
Java-Implementierung von Mohsens Code
Beachten Sie, dass alle Ganzzahlen als float (dh 1f) deklariert sind und float sein müssen, da Sie sonst graue Farben wählen.
HSL zu 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 zu 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
Ich glaube, dies ist die Quelle für einige der anderen Antworten hier.
Hier ist der Code aus Mohsens Antwort in C #, wenn es jemand anderes will. Hinweis: Colorist eine benutzerdefinierte Klasse und Vector4stammt von OpenTK. Beide können leicht durch etwas anderes Ihrer Wahl ersetzt werden.
Hsl nach 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 nach 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);}
Eingabe: Hex-Farbe im Format: [#] 0f4 oder [#] 00ff44 (Nummernzeichen optional)
Ausgabe: HSL in Grad, Prozent, Prozent
/**
* 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 zu HSL
Eingabe: RGB im Bereich 0-255 Ausgabe: HSL in Grad, Prozent, Prozent.
/**
*
*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 (Bereich 0-1) bis Grad, Prozent, Prozent Format
Für die mathematischen Berechnungen ist HSL im Bereich von 0 bis 1 einfacher zu handhaben, für die menschliche Lesbarkeit jedoch einfacher in Grad, Prozent, Prozent. Diese Funktion nimmt HSL in den Bereichen 0-1 und gibt HSL in Grad, Prozent, Prozent zurück.
/**
* 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 (Grad, Prozent, Prozent Format) bis HSL im Bereich 0-1
Diese Funktion konvertiert HSL im Format Grad, Prozent, Prozent in die Bereiche 0-1, um die Berechnung zu vereinfachen.
/**
* 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 zu RGB
Eingabe: HSL im Format Grad, Prozent, Prozent Ausgabe: RGB im Format 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;}
Farbton zu RGB
Diese Funktion wird von hslToRgb aufgerufen, um den Farbton in die separaten RGB-Werte umzuwandeln.
/**
* 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 zu Hex
Eingabe: HSL im Format Grad, Prozent, Prozent Ausgabe: Hex im Format 00ff22(kein Nummernzeichen).
Konvertiert in RGB und konvertiert dann separat in 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;}
Ich habe eine rgbToHslÄnderung vorgenommen , möglicherweise möchten Sie Ihren PHP-Code aktualisieren. Es gab / gibt einen Fehler im Code. In rgbToHsl () s = maxSub / (2 - maxSub)sollte seins = maxSub / (2 - maxAdd)
Lex
@Lex Laut hier und hier ist mein Code tatsächlich korrekt. Ich denke, Sie könnten das if l < 0.5mit dem verwechseln else. Könnten Sie Ihr Denken erklären? Vielen Dank, dass Sie sich die Zeit genommen haben, Feedback zu geben!
Cullub
1
Entschuldigung, Sie haben Recht, aber es gibt immer noch ein Problem mit der Reihenfolge der Operationen. # 8cd08c an HSL mit dieser Berechnung, (2 - maxSub) = 1.7333333333333334wenn es wie im zweiten Link-Beispiel sein sollte ( 2 - max - min ) = 0.6352941176470588. Durch 2 - maxAdddie Verwendung bin ich der Ausgabe von Photoshops immer näher gekommen, sodass ich davon ausgegangen bin, dass sie korrekt ist.
Lex
Oh ok. Vielen Dank für den Hinweis! Ich habe es jetzt behoben. Hoffe das ist hilfreich!
Dies sollte die akzeptierte Antwort sein ... viel einfacher und intuitiver! Können Sie den Algorithmus umkehren?
JoelFan
@ JoelFan - Es ist einfach, aber nicht korrekt . Es gibt keine Möglichkeit für reine rationale Ausdrücke (mit nur +, -, *, und /) - wie per Definition für die Farbkonvertierung verwendet werden - sie mit Hilfe der auszudrücken sineFunktionen mit demselben unabhängig (Input) Variablen. Trotzdem ist es schön , das Prinzip zu verstehen (aber nicht, um Konvertierungen durchzuführen).
MarianD
Das Problem bei dieser Lösung ist, dass DURCHSCHNITT immer gleich NULL ist: (R1 + G1 + B1) = L*[ SIN(H) + SIN(H+120) + SIN(H+240) ]- und wenn wir nun die Formel sin(a)+sin(b) = 2*sin((a+b)/2)*cos((a-b)/2)für die ersten beiden Sünden verwenden, erhalten wir: AVERAGE=L*( sin(h+60) + sin(h+240) )und wieder AVERAGE= L*2*sin(h+150)*cos(-180/2) = 0(da cos (-180/2) = cos (90) = 0). Die Berechnung der Sättigung ist also falsch und tatsächlich funktioniert die Sättigung hier als Luminanz.
Kamil Kiełczewski
@JoelFan Das zweite Problem bei dieser Lösung ist, dass wir H um 180 Grad hinzufügen müssen, um eine "kompatible" Version mit en.wikipedia.org/wiki/HSL_and_HSV#Converting_to_RGB zu haben (Testfall: rote Farbe für H = 0), aber auch ist immer noch ein Problem mit der Anzahl der Farben - in der obigen Lösung werden die Farben Gelb, Magenta und Cyan nicht verwendet und / oder falsch zugeordnet. Es gibt js Geige mit Vergleich: jsfiddle.net/Lamik/9s24uc1o/10
Kamil Kiełczewski
3
Hier ist eine schnelle, supereinfache, verzweigungslose Version in GLSL:
Hier ist die modifizierte Javascript-Funktion, die den Farbton in eingestellten 0-360 Grad ausgibt.
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));
Es wurde ursprünglich in CoffeeScript geschrieben . Ich habe es mit einem Online-Konverter in JavaScript konvertiert und den Mechanismus entfernt, um zu überprüfen, ob die Benutzereingabe ein gültiger RGB-Wert ist. Diese Antwort funktionierte für meinen Anwendungsfall, da die am häufigsten gewählte Antwort auf diesen Beitrag keinen gültigen HSL-Wert ergab.
Beachten Sie, dass ein hslaWert zurückgegeben wird, ader Deckkraft / Transparenz darstellt. 0ist vollständig transparent und 1vollständig undurchsichtig.
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];}
Ich habe dies als Grundlage für eine Python-Methode verwendet. Vielen Dank.
JayJay123
Dies ist keine HSL für RGB, wie das Poster fragt
Bryc
1
Wenn Sie stattdessen RGB zum HSV benötigen und umgekehrt:
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)];}
Hier ist der Code aus Mohsens Antwort in C #, der speziell für Unity3D entwickelt wurde. Es wurde aus der C # -Antwort von Alec Thilenius oben übernommen.
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);}}
Für alle, die sagten, dass die Garry Tan-Lösung falsch von RGB nach HSL und zurück konvertiert. Es, weil er einen Bruchteil der Zahl in seinem Code weggelassen hat. Ich habe seinen Code (Javascript) korrigiert. Entschuldigung für den Link zur russischen Sprache, aber zum Fehlen von Englisch - 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)}};};
Technisch gesehen ist das wohl gar nicht so Zeilen Code - es ist einfach automatisch. Abhängig von Ihrer Umgebung können Sie möglicherweise genau damit durchkommen. Nicht, dass es hier nicht viele sehr nachdenkliche Antworten gibt. Ich weiß nicht, was dein Ziel ist.
Was ist nun, wenn Sie von rbg | a nach hsl | a konvertieren möchten?
C ++ - Implementierung mit wahrscheinlich besserer Leistung als @ Mohsen-Code. Es wird ein [0-6] -Bereich für den Farbton verwendet, wobei die Division und Multiplikation mit 6 vermieden wird. Der S- und L-Bereich beträgt [0,1].
Please.HEX_to_HSV('#ffeb3b')
Antworten:
Garry Tan hat eine Javascript-Lösung in seinem Blog veröffentlicht (die er einem inzwischen nicht mehr existierenden mjijackson.com zuschreibt, aber hier archiviert ist und der ursprüngliche Autor einen Kern hat - dank user2441511).
Der Code wird unten erneut veröffentlicht:
HSL zu RGB:
RGB zu HSL:
quelle
Math.round
kleine Ungenauigkeiten am unteren und oberen Ende (Werte von 0 und 255) der Skala mit sich bringt. Werte, die sich nicht an den Enden des Bereichs befinden, können entweder auf- oder abgerundet werden, um ihren Wert zu erreichen. Werte können jedoch nur auf 0 oder bis zu 255 abgerundet werden. Dies bedeutet, dass der Wertebereich, der auf 0 und 255 abgebildet wird, genau ist die Hälfte davon für andere Werte. Verwenden Sie stattdessen diese Formel, um dies zu beheben :min(floor(val*256),255)
. Dies macht das Mapping nahezu perfekt.h + 1/3
und verwendenh - 1/3
. In vielen Sprachen wird die Ganzzahldivision verwendet, wobei1/3
Null ist. Verwenden Sie stattdessen Float-Literale, um korrekte Ergebnisse zu erhaltenh + 1.0/3.0
.Den einfachsten Weg gefunden, Python zur Rettung : D.
quelle
Color::HSL.new(40,50,60).to_rgb
Java-Implementierung von Mohsens Code
Beachten Sie, dass alle Ganzzahlen als float (dh 1f) deklariert sind und float sein müssen, da Sie sonst graue Farben wählen.
HSL zu RGB
RGB zu HSL
quelle
Der Artikel für HSL und HSV auf Wikipedia enthält einige Formeln. Die Berechnungen sind etwas knifflig, daher kann es hilfreich sein, sich vorhandene Implementierungen anzusehen .
quelle
Wenn Sie nach etwas suchen, das definitiv der CSS-Semantik für HSL und RGB entspricht, können Sie den in der CSS 3-Spezifikation angegebenen Algorithmus verwenden , der lautet:
Ich glaube, dies ist die Quelle für einige der anderen Antworten hier.
quelle
C # -Code aus Mohsens Antwort.
Hier ist der Code aus Mohsens Antwort in C #, wenn es jemand anderes will. Hinweis:
Color
ist eine benutzerdefinierte Klasse undVector4
stammt von OpenTK. Beide können leicht durch etwas anderes Ihrer Wahl ersetzt werden.Hsl nach Rgba
Rgba nach Hsl
quelle
PHP-Implementierung von Chris 'C # -Code
Auch von hier aus , was die Mathematik sehr gut erklärt.
Dies ist im Grunde eine Reihe von Funktionen, die in und aus HSL (Hue Saturation Lightness) konvertiert werden können.
Getestet und arbeitet an PHP 5.6.15
TL; DR : Den vollständigen Code finden Sie hier auf Pastebin .
Hex zu HSL
Eingabe: Hex-Farbe im Format: [#] 0f4 oder [#] 00ff44 (Nummernzeichen optional)
Ausgabe: HSL in Grad, Prozent, Prozent
RGB zu HSL
Eingabe: RGB im Bereich 0-255 Ausgabe: HSL in Grad, Prozent, Prozent.
HSL (Bereich 0-1) bis Grad, Prozent, Prozent Format
Für die mathematischen Berechnungen ist HSL im Bereich von 0 bis 1 einfacher zu handhaben, für die menschliche Lesbarkeit jedoch einfacher in Grad, Prozent, Prozent. Diese Funktion nimmt HSL in den Bereichen 0-1 und gibt HSL in Grad, Prozent, Prozent zurück.
HSL (Grad, Prozent, Prozent Format) bis HSL im Bereich 0-1
Diese Funktion konvertiert HSL im Format Grad, Prozent, Prozent in die Bereiche 0-1, um die Berechnung zu vereinfachen.
HSL zu RGB
Eingabe: HSL im Format Grad, Prozent, Prozent Ausgabe: RGB im Format
255, 255, 255
.Farbton zu RGB
Diese Funktion wird von hslToRgb aufgerufen, um den Farbton in die separaten RGB-Werte umzuwandeln.
HSL zu Hex
Eingabe: HSL im Format Grad, Prozent, Prozent Ausgabe: Hex im Format
00ff22
(kein Nummernzeichen).Konvertiert in RGB und konvertiert dann separat in Hex.
quelle
rgbToHsl
Änderung vorgenommen , möglicherweise möchten Sie Ihren PHP-Code aktualisieren. Es gab / gibt einen Fehler im Code. In rgbToHsl ()s = maxSub / (2 - maxSub)
sollte seins = maxSub / (2 - maxAdd)
if l < 0.5
mit dem verwechselnelse
. Könnten Sie Ihr Denken erklären? Vielen Dank, dass Sie sich die Zeit genommen haben, Feedback zu geben!(2 - maxSub) = 1.7333333333333334
wenn es wie im zweiten Link-Beispiel sein sollte( 2 - max - min ) = 0.6352941176470588
. Durch2 - maxAdd
die Verwendung bin ich der Ausgabe von Photoshops immer näher gekommen, sodass ich davon ausgegangen bin, dass sie korrekt ist.So mache ich es, was leicht zu merken ist, wenn man sich RGB als drei Speichen auf einem Rad im Abstand von 120 Grad vorstellt.
Der schwierige Teil ist die Sättigung, die auf den Durchschnitt dieser drei reduziert wird.
quelle
+
,-
,*
, und/
) - wie per Definition für die Farbkonvertierung verwendet werden - sie mit Hilfe der auszudrückensine
Funktionen mit demselben unabhängig (Input) Variablen. Trotzdem ist es schön , das Prinzip zu verstehen (aber nicht, um Konvertierungen durchzuführen).(R1 + G1 + B1) = L*[ SIN(H) + SIN(H+120) + SIN(H+240) ]
- und wenn wir nun die Formelsin(a)+sin(b) = 2*sin((a+b)/2)*cos((a-b)/2)
für die ersten beiden Sünden verwenden, erhalten wir:AVERAGE=L*( sin(h+60) + sin(h+240) )
und wiederAVERAGE= L*2*sin(h+150)*cos(-180/2) = 0
(da cos (-180/2) = cos (90) = 0). Die Berechnung der Sättigung ist also falsch und tatsächlich funktioniert die Sättigung hier als Luminanz.Hier ist eine schnelle, supereinfache, verzweigungslose Version in GLSL:
Wird nicht viel kürzer als das ~
Link zum ursprünglichen Proof-of-Concept: https://www.shadertoy.com/view/XljGzV
(Haftungsausschluss: nicht mein Code!)
quelle
Hier ist die modifizierte Javascript-Funktion, die den Farbton in eingestellten 0-360 Grad ausgibt.
quelle
Ich habe das von Brandon Mathis ' HSL Picker bekommen Quellcode .
Es wurde ursprünglich in CoffeeScript geschrieben . Ich habe es mit einem Online-Konverter in JavaScript konvertiert und den Mechanismus entfernt, um zu überprüfen, ob die Benutzereingabe ein gültiger RGB-Wert ist. Diese Antwort funktionierte für meinen Anwendungsfall, da die am häufigsten gewählte Antwort auf diesen Beitrag keinen gültigen HSL-Wert ergab.
Beachten Sie, dass ein
hsla
Wert zurückgegeben wird,a
der Deckkraft / Transparenz darstellt.0
ist vollständig transparent und1
vollständig undurchsichtig.quelle
Wenn Sie stattdessen RGB zum HSV benötigen und umgekehrt:
quelle
Unity3D C # -Code aus Mohsens Antwort.
Hier ist der Code aus Mohsens Antwort in C #, der speziell für Unity3D entwickelt wurde. Es wurde aus der C # -Antwort von Alec Thilenius oben übernommen.
quelle
Für alle, die sagten, dass die Garry Tan-Lösung falsch von RGB nach HSL und zurück konvertiert. Es, weil er einen Bruchteil der Zahl in seinem Code weggelassen hat. Ich habe seinen Code (Javascript) korrigiert. Entschuldigung für den Link zur russischen Sprache, aber zum Fehlen von Englisch - HSL-Wiki
quelle
Ein in Javascript festgelegter hsl | a-Farbwert wird sofort in rgb | a konvertiert. Sie müssen dann nur noch auf den berechneten Stilwert zugreifen
Technisch gesehen ist das wohl gar nicht so Zeilen Code - es ist einfach automatisch. Abhängig von Ihrer Umgebung können Sie möglicherweise genau damit durchkommen. Nicht, dass es hier nicht viele sehr nachdenkliche Antworten gibt. Ich weiß nicht, was dein Ziel ist.
Was ist nun, wenn Sie von rbg | a nach hsl | a konvertieren möchten?
quelle
C ++ - Implementierung mit wahrscheinlich besserer Leistung als @ Mohsen-Code. Es wird ein [0-6] -Bereich für den Farbton verwendet, wobei die Division und Multiplikation mit 6 vermieden wird. Der S- und L-Bereich beträgt [0,1].
quelle
Mit H, S und L im [0,1] Bereich:
quelle
Ich brauchte ein wirklich leichtes, es ist nicht 100%, aber es kommt nah genug für einige Anwendungsfälle.
quelle
PHP-Implementierung von @ Mohsens Code (einschließlich Test!)
Tut mir leid, dies erneut zu posten. Aber ich habe wirklich keine andere Implementierung gesehen, die die Qualität bietet, die ich brauchte.
quelle