public
Last active

Test of various hsl2rgb conversions

  • Download Gist
hst2rgb-test.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
var assert = require('assert');
 
var tests = [
{hsl: [0, 0, 0], rgb: [0, 0, 0]}, // black
{hsl: [0, 0, 1], rgb: [255, 255, 255]}, // white
{hsl: [0, 1, 0.5], rgb: [255, 0, 0]}, // red
{hsl: [120, 1, 0.5], rgb: [0, 255, 0]}, // green
{hsl: [240, 1, 0.5], rgb: [0, 0, 255]}, // blue
 
// http://www.december.com/html/spec/colorcodes.html
{hsl: [205, 0.55, 0.75], rgb: [155, 196, 226]}, // cerulean blue
{hsl: [131, 0.91, 0.86], rgb: [189, 252, 201]}, // mint green
{hsl: [9, 0.59, 0.34], rgb: [138, 51, 36]}, // burnt umber
 
// Brokers
// Calculations from http://serennu.com/colour/hsltorgb.php
{hsl: [350, 0.9, 0.1], rgb: [48, 3, 10]},
{hsl: [350, 0.9, 0.5], rgb: [242, 13, 51]},
{hsl: [350, 0.9, 0.8], rgb: [250, 158, 173]},
];
 
var converters = [
// From node-tint
function (h, s, l) {
if (!s) return [l * 255, l * 255, l * 255];
 
var v = l <= 0.5 ? l*(1+s) : l+s-l*s;
if (!v) return [0, 0, 0];
 
var min = 2*l-v;
var sv = (v-min)/l
h = (h % 360) / 60;
var sextant = h | 0;
var fract = h-sextant;
v *= 255;
min *= 255;
switch (sextant) {
case 0: return [Math.round(v), Math.round(min+v*sv*fract), Math.round(min)];
case 1: return [Math.round(v-v*sv*fract), Math.round(v), Math.round(min)];
case 2: return [Math.round(min), Math.round(v), Math.round(min+v*sv*fract)];
case 3: return [Math.round(min), Math.round(v-v*sv*fract), Math.round(v)];
case 4: return [Math.round(min+v*sv*fract), Math.round(min), Math.round(v)];
case 5: return [Math.round(v), Math.round(min), Math.round(v-v*sv*fract)];
}
},
// From farbtastic
function(h, s, l) {
// normalize input.
h = h / 360;
 
var m1, m2, r, g, b;
 
var hueToRGB = function (m1, m2, h) {
h = (h + 1) % 1;
if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
if (h * 2 < 1) return m2;
if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6;
return m1;
};
 
m2 = (l <= 0.5) ? l * (s + 1) : l + s - l * s;
m1 = l * 2 - m2;
return [
hueToRGB(m1, m2, h + 0.33333) * 255,
hueToRGB(m1, m2, h) * 255,
hueToRGB(m1, m2, h - 0.33333) * 255
];
},
// @see http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
function (h, s, l) {
// normalize input.
h = h / 360;
 
var r, g, b;
 
if (s == 0) {
r = g = b = l; // achromatic
} else {
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 [r * 255, g * 255, b * 255];
}
];
 
var run = 0;
var fail = 0;
converters.forEach(function(hsl2rgb, idx) {
console.warn("Method " + (idx + 1));
tests.forEach(function(test) {
run++;
var rgb = hsl2rgb(test.hsl[0], test.hsl[1],test.hsl[2]);
rgb[0] = Math.round(rgb[0]);
rgb[1] = Math.round(rgb[1]);
rgb[2] = Math.round(rgb[2]);
 
try {
assert.deepEqual(test.rgb, rgb);
}
catch(e) {
fail++
console.warn(">> " + e.toString());
}
});
});
 
console.log(">> Passed " + (run - fail) + " of " + run);

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.