| 101 | // ============================================================ |
| 102 | |
| 103 | function labToRgb(L, a, b) { |
| 104 | const fy = (L + 16) / 116; |
| 105 | const fx = a / 500 + fy; |
| 106 | const fz = fy - b / 200; |
| 107 | const cube = v => v ** 3 > 0.008856 ? v ** 3 : (v - 16 / 116) / 7.787037; |
| 108 | const x = cube(fx) * 0.95047; |
| 109 | const y = cube(fy) * 1.00000; |
| 110 | const z = cube(fz) * 1.08883; |
| 111 | let r = x * 3.2404542 - y * 1.5371385 - z * 0.4985314; |
| 112 | let g = -x * 0.9692660 + y * 1.8760108 + z * 0.0415560; |
| 113 | let bv = x * 0.0556434 - y * 0.2040259 + z * 1.0572252; |
| 114 | const toSrgb = c => c <= 0.0031308 ? 12.92 * c : 1.055 * Math.pow(Math.max(0, c), 1 / 2.4) - 0.055; |
| 115 | return [ |
| 116 | Math.max(0, Math.min(255, Math.round(toSrgb(r) * 255))), |
| 117 | Math.max(0, Math.min(255, Math.round(toSrgb(g) * 255))), |
| 118 | Math.max(0, Math.min(255, Math.round(toSrgb(bv) * 255))), |
| 119 | ]; |
| 120 | } |
| 121 | |
| 122 | /** |
| 123 | * Median Cut entirely in CIELAB space. |