Conversões entre Espaços de Cores
Neste artigo, vamos explorar como realizar conversões entre diferentes espaços de cores a partir do modelo RGB. Exemplos de código serão apresentados em JavaScript.
HEX
Converter uma cor RGB para o formato HEX envolve transformar valores decimais em hexadecimais. Veja o exemplo:
function rgbParaHex(r, g, b, incluirPrefixo = true) {
const hex = ((r << 16) | (g << 8) | b).toString(16).padStart(6, '0');
return incluirPrefixo ? `#${hex}` : hex;
}
CMYK
A conversão de RGB para CMYK requer dois passos: primeiro convertemos RGB para CMY e depois ajustamos para CMYK.
function rgbParaCmyk(r, g, b) {
let c = 1 - r / 255;
let m = 1 - g / 255;
let y = 1 - b / 255;
let k = Math.min(c, m, y);
if (k === 1) {
return { c: 0, m: 0, y: 0, k: 100 };
} else {
c = ((c - k) / (1 - k)) * 100;
m = ((m - k) / (1 - k)) * 100;
y = ((y - k) / (1 - k)) * 100;
k *= 100;
return { c: Math.round(c), m: Math.round(m), y: Math.round(y), k: Math.round(k) };
}
}
HSV
Para converter RGB para HSV, primeiro normalizaoms os valores RGB, então calculamos H, S e V.
function rgbParaHsv(r, g, b) {
r /= 255; g /= 255; b /= 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
const delta = max - min;
let h = 0, s = 0, v = max;
if (delta > 0) {
s = max === 0 ? 0 : delta / max;
switch(max){
case r: h = (g - b) / delta + (g < b ? 6 : 0); break;
case g: h = (b - r) / delta + 2; break;
case b: h = (r - g) / delta + 4; break;
}
h /= 6;
}
return { h: Math.round(h * 360), s: Math.round(s * 100), v: Math.round(v * 100) };
}
HSL
Similar ao HSV, mas com ligeiras diferenças na fórmula para calcular L e S.
function rgbParaHsl(r, g, b) {
r /= 255; g /= 255; b /= 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
const delta = max - min;
let h = 0, s = 0, l = (max + min) / 2;
if (delta > 0) {
s = delta === 0 || max + min === 2 ? 0 : delta / (1 - Math.abs(2 * l - 1));
switch(max){
case r: h = (g - b) / delta + (g < b ? 6 : 0); break;
case g: h = (b - r) / delta + 2; break;
case b: h = (r - g) / delta + 4; break;
}
h /= 6;
}
return { h: Math.round(h * 360), s: Math.round(s * 100), l: Math.round(l * 100) };
}
LAB
LAB é um espaço de cores mais complexo que necessita de um passo intermediário através do XYZ.
function rgbParaXyz(r, g, b) {
r = gamma(r / 255);
g = gamma(g / 255);
b = gamma(b / 255);
const x = 0.4124564 * r + 0.3575761 * g + 0.1804375 * b;
const y = 0.2126729 * r + 0.7151522 * g + 0.072175 * b;
const z = 0.0193339 * r + 0.119192 * g + 0.9503041 * b;
return { x, y, z };
}
function xyzParaLab(x, y, z) {
x /= 0.950456; y /= 1; z /= 1.088754;
x = f(x); y = f(y); z = f(z);
const l = 116 * y - 16;
const a = 500 * (x - y);
const b = 200 * (y - z);
return { l: Math.round(l), a: Math.round(a), b: Math.round(b) };
}
function rgbParaLab(r, g, b) {
const xyz = rgbParaXyz(r, g, b);
return xyzParaLab(xyz.x, xyz.y, xyz.z);
}
function f(t) {
return t > 0.008856 ? Math.pow(t, 1/3) : 7.787037037037035 * t + 0.13793103448275862;
}
function gamma(t) {
return t > 0.04045 ? Math.pow((t + 0.055) / 1.055, 2.4) : t / 12.92;
}