Sunday, November 04, 2012

Simple Javascript RGB/HSV converter

This is a simple and straightforward converter between RGB and HSV values, with RGBs from 0 - 255 and HSV values with hue from 0 - 359 and S/V from 0 - 1. I wrote it for an as yet unfinished HTML5 red-eye correction tool, but I'll be unable to devote much time to side-projects until after the holidays, so I thought I'd put this up now in case someone found it useful.

Enjoy!


function getHSV(r, g, b) {
  var h, s, v, max, delta;

  // v (value) is the highest of the RGB values scaled to [0-1]
  max = Math.max(r, Math.max(g, b));
  if (max == 0) return [0, 0, 0];
  v = max / 255;

  // delta is the difference between the largest and smallest of RGB
  delta = max - Math.min(r, Math.min(g, b));
  if (delta == 0) return [0, 0, v]; // No delta = grey, only v is significant

  // s (saturation) is delta divided by max
  s = delta / max;

  // h (hue) is a number in degrees describing the color's angle on the hsv color wheel
  if      (r == max) h =     (g - b) / delta;
  else if (g == max) h = 2 + (b - r) / delta;
  else if (b == max) h = 4 + (r - g) / delta;

  // convert hue to degrees
  if (h < 0) h += 6;
  h *= 60;

  return [h, s, v];
}

function getRGB(h, s, v) {
  var quadrant, max, mid, min, fraction;
  max = Math.round(v * 255);
  if( s == 0 ) return ([max, max, max]); // Greys

  // Quadrant is between 0 and 5, where 0, 2, and 4 are red, green, and blue
  h /= 60;
  quadrant = Math.floor(h);

  // fraction is distance away from quadrant representing hue's primary color
  fraction = (quadrant % 2 == 0) ? (1 - h % 1) : h % 1;

  // min and mid are the smaller two RGB colors in the final return array
  // We don't know what primary colors they represent...
  min = Math.round(max * ( 1 - s ));
  mid = Math.round(max * ( 1 - s * fraction ));

  // ...until we check what quadrant we're in
  switch (quadrant) {
    // reds
    case 5: return [max, min, mid];
    case 0: return [max, mid, min];
    // greens
    case 1: return [mid, max, min];
    case 2: return [min, max, mid];
    // blues
    case 3: return [min, mid, max];
    case 4: return [mid, min, max];
  }
}

No comments:

Post a Comment