Skip to content

Instantly share code, notes, and snippets.

@btd
Last active March 22, 2020 07:31
Show Gist options
  • Save btd/702da3372f1424c1f7f9862b4166c87e to your computer and use it in GitHub Desktop.
Save btd/702da3372f1424c1f7f9862b4166c87e to your computer and use it in GitHub Desktop.
Color space conversions, RGB, XYZ, CIE Lab
export class RGB {
constructor(r, g, b, a) {
this.r = r;
this.g = g;
this.b = b;
this.a = a;
}
}
function pivotRgb(n) {
return (n > 0.04045 ? Math.pow((n + 0.055) / 1.055, 2.4) : n / 12.92) * 100.0;
}
export function RGBtoXYZ(color) {
let r = pivotRgb(color.r / 255.0);
let g = pivotRgb(color.g / 255.0);
let b = pivotRgb(color.b / 255.0);
// Observer. = 2°, Illuminant = D65
let x = r * 0.4124 + g * 0.3576 + b * 0.1805;
let y = r * 0.2126 + g * 0.7152 + b * 0.0722;
let z = r * 0.0193 + g * 0.1192 + b * 0.9505;
return new XYZ(x, y, z);
}
export class XYZ {
constructor(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
}
}
const EPS = 0.008856; // Intent is 216/24389
const KAPPA = 903.3; // Intent is 24389/27
function cubicRoot(n) {
return Math.pow(n, 1.0 / 3.0);
}
function pivotXyz(n) {
return n > EPS ? cubicRoot(n) : (KAPPA * n + 16) / 116;
}
const whiteXYZ = new XYZ(
95.047,
100.000,
108.883
);
export function XYZtoCIELAB(color) {
let x = pivotXyz(color.x / whiteXYZ.x);
let y = pivotXyz(color.y / whiteXYZ.y);
let z = pivotXyz(color.z / whiteXYZ.z);
let L = Math.max(0, 116 * y - 16);
let a = 500 * (x - y);
let b = 200 * (y - z);
return new Lab(L, a, b);
}
export function RGBtoCIELAB(color) {
return XYZtoCIELAB(RGBtoXYZ(color));
}
export class Lab {
constructor(L, a, b) {
this.L = L;
this.a = a;
this.b = b;
}
// deltaE
delta(color) {
let dL = this.L - color.L;
let C1 = Math.sqrt(this.a * this.a + this.b * this.b);
let C2 = Math.sqrt(color.a * color.a + color.b * color.b);
let dC = C1 - C2;
let da = this.a - color.a;
let db = this.b - color.b;
let dH = Math.sqrt(da * da + db * db - dC * dC);
const kL = 1;
const K1 = 0.045;
const K2 = 0.015;
const kC = 1;
const kH = 1;
let SL = 1;
let SC = 1 + K1 * C1;
let SH = 1 + K2 * C1;
return Math.sqrt(
Math.pow(dL/(kL*SL), 2) +
Math.pow(dC/(kC*SC), 2) +
Math.pow(dH/(kH*SH), 2)
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment