Why does this Javascript RGB for HSL code not work?

I found this RGB for HSL script above http://www.mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript . I can not find other worthy little ones. The problem is that this code does not even work. Does anyone know why? (I don’t know a bit of color math, but maybe it returns extra?)

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]; } 

Edit: when I run rgbToHsl(126,210,22) , it gives me [.24, .81, .45] which is HSL for orange.

+13
javascript colors rgb hsl
Feb 27 '10 at 7:17
source share
3 answers

The resulting HSV matrix should be interpreted as three fractions. For some programs, if you want to express HSV as integers, you multiply the "H" value by 360 and the "S" and "V" values ​​by 100. The HSV value that you specify for your green RGB hue [126, 210, 22 ] is the HSV [87, 81, 45] in integers. You can change the function to return such integers if you want:

 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 [Math.floor(h * 360), Math.floor(s * 100), Math.floor(l * 100)]; } 

[edit], who said that he still gives me something with a brightness ("L" or "V") that is too dark; Gimp says the HSV value should be [90, 80, 82] or in fractional terms [.20, .80, .82].

[other edit] Well, one problem may be that HSL and HSV are different schemes ... still looking around.

OK, if someone wants RGB to be HSV (for example, you saw in Gimp, for example), here is the version of this:

 function rgbToHsv(r, g, b) { var min = Math.min(r, g, b), max = Math.max(r, g, b), delta = max - min, h, s, v = max; v = Math.floor(max / 255 * 100); if ( max != 0 ) s = Math.floor(delta / max * 100); else { // black return [0, 0, 0]; } if( r == max ) h = ( g - b ) / delta; // between yellow & magenta else if( g == max ) h = 2 + ( b - r ) / delta; // between cyan & yellow else h = 4 + ( r - g ) / delta; // between magenta & cyan h = Math.floor(h * 60); // degrees if( h < 0 ) h += 360; return [h, s, v]; } 
+23
Feb 27 '10 at 19:35
source share

Try this ( wiki , error analysis , more: hsl2rgb , rgb2hsv , hsv2rgb and sl22sv ):

 // in: r,g,b in [0,1], out: h in [0,360) and s,v in [0,1] function rgb2hsl(r,g,b) { let a=Math.max(r,g,b), n=a-Math.min(r,g,b), f=(1-Math.abs(a+an-1)); let h= n && ((a==r) ? (gb)/n : ((a==g) ? 2+(br)/n : 4+(rg)/n)); return [60*(h<0?h+6:h), f ? n/f : 0, (a+an)/2]; } 

 function rgb2hsl(r,g,b) { let a=Math.max(r,g,b), n=a-Math.min(r,g,b), f=(1-Math.abs(a+an-1)); let h= n && ((a==r) ? (gb)/n : ((a==g) ? 2+(br)/n : 4+(rg)/n)); return [60*(h<0?h+6:h), f ? n/f : 0, (a+an)/2]; } console.log('rgb: (0.36,0.3,0.24) --> hsl: (${rgb2hsl(0.36,0.3,0.24)})'); // --------------- // UX // --------------- rgb= [0,0,0]; hs= [0,0,0]; let $ = x => document.querySelector(x); let hsl2rgb = (h,s,l, a=s*Math.min(l,1-l), f= (n,k=(n+h/30)%12) => l - a*Math.max(Math.min(k-3,9-k,1),-1)) => [f(0),f(8),f(4)]; function changeRGB(i,e) { rgb[i]=e.target.value/255; hs = rgb2hsl(...rgb); refresh(); } function changeHS(i,e) { hs[i]=e.target.value/(i?255:1); rgb= hsl2rgb(...hs); refresh(); } function refresh() { rr = rgb.map(x=>x*255|0).join(', ') tr = 'RGB: ${rr}' th = 'HSL: ${hs.map((x,i)=>i? (x*100).toFixed(2)+'%':x|0).join(', ')}' $('.box').style.backgroundColor='rgb(${rr})'; $('.infoRGB').innerHTML='${tr}'; $('.infoHS').innerHTML ='${th}'; $('#r').value=rgb[0]*255; $('#g').value=rgb[1]*255; $('#b').value=rgb[2]*255; $('#h').value=hs[0]; $('#s').value=hs[1]*255; $('#l').value=hs[2]*255; } refresh(); 
 .box { width: 50px; height: 50px; margin: 20px; } body { display: flex; } 
 <div> <input id="r" type="range" min="0" max="255" oninput="changeRGB(0,event)">R<br> <input id="g" type="range" min="0" max="255" oninput="changeRGB(1,event)">G<br> <input id="b" type="range" min="0" max="255" oninput="changeRGB(2,event)">B<br> <pre class="infoRGB"></pre> </div> <div> <div class="box hsl"></div> </div> <div> <input id="h" type="range" min="0" max="360" oninput="changeHS(0,event)">H<br> <input id="s" type="range" min="0" max="255" oninput="changeHS(1,event)">S<br> <input id="l" type="range" min="0" max="255" oninput="changeHS(2,event)">L<br> <pre class="infoHS"></pre><br> </div> 
+2
Jan 07 '19 at 9:32
source share

The function below converts RGB color to Hue saturation color, for example, Photoshop selection picker, the results are in the range:

  • Tint 0-360 (in degrees)
  • Saturation: 0-100 (%)
  • Brightness: 0-100 (%)

I still don’t understand why people use the term HSV (Hue Saturation Value) instead of HSB (Hue Saturation Brightness), anyway it's a matter of terminology, the results are the same

  //Converts to color HSB object (code from here http://www.csgnetwork.com/csgcolorsel4.html with some improvements) function rgb2hsb(r, g, b) { r /= 255; g /= 255; b /= 255; // Scale to unity. var minVal = Math.min(r, g, b), maxVal = Math.max(r, g, b), delta = maxVal - minVal, HSB = {hue:0, sat:0, bri:maxVal}, del_R, del_G, del_B; if( delta !== 0 ) { HSB.sat = delta / maxVal; del_R = (((maxVal - r) / 6) + (delta / 2)) / delta; del_G = (((maxVal - g) / 6) + (delta / 2)) / delta; del_B = (((maxVal - b) / 6) + (delta / 2)) / delta; if (r === maxVal) {HSB.hue = del_B - del_G;} else if (g === maxVal) {HSB.hue = (1 / 3) + del_R - del_B;} else if (b === maxVal) {HSB.hue = (2 / 3) + del_G - del_R;} if (HSB.hue < 0) {HSB.hue += 1;} if (HSB.hue > 1) {HSB.hue -= 1;} } HSB.hue *= 360; HSB.sat *= 100; HSB.bri *= 100; return HSB; } 

Usage example:

 var hsb = rgb2hsb(126,210,22); alert("hue = " + hsb.hue + "saturation = " + hsb.sat + "brightness = " + hsb.bri); 
+1
May 30 '11 at 18:14
source share



All Articles