0

Lets say I give you a hex color #f9090 how would u determine if this color is orange tinted?

If previous is impossible then would it be possible with a RGB value?

const coloTint = getColorTint('#f90')
/* should log 'orange' 
Zenel Shabani
  • 290
  • 2
  • 11
  • 2
    A hex color code is fundamentally just a number, expressed in base 16. You can simply define what number range or ranges you'd regard as "orange" and test whether the number is within that range… – deceze Sep 30 '20 at 12:00
  • 1
    should `#f91` be marked as orange too? When yes, you need to convert your RGB color to HSL and check the H-Value – Sysix Sep 30 '20 at 12:02
  • What's your definition of "red"? – Liam Sep 30 '20 at 12:08
  • Blood is red for example? It should be able to simply say if its red-ish or yellow-ish or blue-ish ... The question is simple, but the approach to achieving it is difficult it seems, i like the idea of predefining ranges for the color groups and then just checking if the value is between those – Zenel Shabani Sep 30 '20 at 12:27
  • I've never done this sort of thing in JS but you probably want to take a look at the HSV colorspace and some answers like this might be helpful once you understand how that works: https://stackoverflow.com/questions/8022885/rgb-to-hsv-color-in-javascript – PeterJ Sep 30 '20 at 12:47

1 Answers1

3

That's pretty straight forward if you convert your hex code to hsv and use a lookup table to map the hue value to a color name.

Note that using this logic, the name for the hex code wouldn't be orange, but rather red. To get orange as a result, your color would need a hue value of at least 30° (#f9c000)

If you need orange for that value, you can adjust the lookup table to fit you needs.

(pardon me if the translations aren't correct. I just pasted the table into google translate)

const hex = '#f90900';
const name = hex2name(hex);
console.log (`Name of '${hex}' is '${name}'`);


const orangeHSV = [30, 1, 249];
const orangeRGB = hsv2rgb(...orangeHSV);
const orangeHEX = rgb2hex(...orangeRGB);
console.log (`hex for first orange value is '${orangeHEX}'`);

const test = hex2name(orangeHEX);
console.log (`Test if ${orangeHEX} yields orange: ${test}`)
<script>
// https://stackoverflow.com/a/54024653/1487756
function hsv2rgb(h,s,v) {                              
  let f= (n,k=(n+h/60)%6) => v - v*s*Math.max( Math.min(k,4-k,1), 0);     
  return [f(5),f(3),f(1)];       
}   

// https://stackoverflow.com/a/54070620/1487756
function rgb2hsv(r,g,b) {
  let v=Math.max(r,g,b), n=v-Math.min(r,g,b);
  let h= n && ((v==r) ? (g-b)/n : ((v==g) ? 2+(b-r)/n : 4+(r-g)/n)); 
  return [60*(h<0?h+6:h), v&&n/v, v];
} 

const clrLkp = [["red", 0],["vermilion", 15],["brown", 20],["orange", 30],["safran", 45],["yellow", 60],["light green yellow", 75],["green yellow", 90],["limett", 105],["dark green", 120],["green", 120],["light blue-green", 135],["blue green", 150],["green cyan", 165],["cyan", 180],["blaucyan", 195],["green blue", 210],["light green blue", 225],["blue", 240],["indigo", 255],["violet", 270],["blue magenta", 285],["magenta", 300],["red magenta", 315],["blue red", 330],["light blue red", 345]].reverse()

const hex2rgb = hex => {
    const parts = hex.slice(1).match(/../g);
    if (!parts || parts.length <3) throw new Error('Invalid hex value');
    const dec = parts.map(p => parseInt(p, 16));
    return dec;
}
const hsv2name = (h,s,v) => clrLkp.find(([clr,val]) => h >= val)[0];
const hex2name = hex => [hex2rgb, rgb2hsv, hsv2name].reduce((a,v) => v(...[a].flat()),hex);

const pad = v => (v+'0').slice(0,2);
const rgb2hex = (r,g,b) => '#' + [r,g,b].map(Math.round).map(n => pad(n.toString(16))).join('');
</script>
Moritz Roessler
  • 8,542
  • 26
  • 51