chroma-js
Version:
JavaScript library for color conversions
68 lines (53 loc) • 2.38 kB
JavaScript
import LAB_CONSTANTS from './lab-constants.js';
import { unpack } from '../../utils/index.js';
const rgb2lab = (...args) => {
const [r, g, b, ...rest] = unpack(args, 'rgb');
const [x, y, z] = rgb2xyz(r, g, b);
const [L, a, b_] = xyz2lab(x, y, z);
return [L, a, b_, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
};
function xyz2lab(x, y, z) {
const { Xn, Yn, Zn, kE, kK } = LAB_CONSTANTS;
const xr = x / Xn;
const yr = y / Yn;
const zr = z / Zn;
const fx = xr > kE ? Math.pow(xr, 1.0 / 3.0) : (kK * xr + 16.0) / 116.0;
const fy = yr > kE ? Math.pow(yr, 1.0 / 3.0) : (kK * yr + 16.0) / 116.0;
const fz = zr > kE ? Math.pow(zr, 1.0 / 3.0) : (kK * zr + 16.0) / 116.0;
return [116.0 * fy - 16.0, 500.0 * (fx - fy), 200.0 * (fy - fz)];
}
function gammaAdjustSRGB(companded) {
const sign = Math.sign(companded);
companded = Math.abs(companded);
const linear =
companded <= 0.04045
? companded / 12.92
: Math.pow((companded + 0.055) / 1.055, 2.4);
return linear * sign;
}
const rgb2xyz = (r, g, b) => {
// normalize and gamma adjust
r = gammaAdjustSRGB(r / 255);
g = gammaAdjustSRGB(g / 255);
b = gammaAdjustSRGB(b / 255);
const { MtxRGB2XYZ, MtxAdaptMa, MtxAdaptMaI, Xn, Yn, Zn, As, Bs, Cs } =
LAB_CONSTANTS;
let x = r * MtxRGB2XYZ.m00 + g * MtxRGB2XYZ.m10 + b * MtxRGB2XYZ.m20;
let y = r * MtxRGB2XYZ.m01 + g * MtxRGB2XYZ.m11 + b * MtxRGB2XYZ.m21;
let z = r * MtxRGB2XYZ.m02 + g * MtxRGB2XYZ.m12 + b * MtxRGB2XYZ.m22;
const Ad = Xn * MtxAdaptMa.m00 + Yn * MtxAdaptMa.m10 + Zn * MtxAdaptMa.m20;
const Bd = Xn * MtxAdaptMa.m01 + Yn * MtxAdaptMa.m11 + Zn * MtxAdaptMa.m21;
const Cd = Xn * MtxAdaptMa.m02 + Yn * MtxAdaptMa.m12 + Zn * MtxAdaptMa.m22;
let X = x * MtxAdaptMa.m00 + y * MtxAdaptMa.m10 + z * MtxAdaptMa.m20;
let Y = x * MtxAdaptMa.m01 + y * MtxAdaptMa.m11 + z * MtxAdaptMa.m21;
let Z = x * MtxAdaptMa.m02 + y * MtxAdaptMa.m12 + z * MtxAdaptMa.m22;
X *= Ad / As;
Y *= Bd / Bs;
Z *= Cd / Cs;
x = X * MtxAdaptMaI.m00 + Y * MtxAdaptMaI.m10 + Z * MtxAdaptMaI.m20;
y = X * MtxAdaptMaI.m01 + Y * MtxAdaptMaI.m11 + Z * MtxAdaptMaI.m21;
z = X * MtxAdaptMaI.m02 + Y * MtxAdaptMaI.m12 + Z * MtxAdaptMaI.m22;
return [x, y, z];
};
export default rgb2lab;
export { rgb2xyz };