亮度 vs L:^* 0 和 100 在光亮(写为 Y 或 L )和亮度(写为 L^* )方面是相同的,但在中间它们却非常不同。我们确定的中间灰色位于 L^* 的中间 50 处,但这与亮度 (Y) 中的 18.4 相关。在 sRGB 中,这是 #777777 或 46.7 \%。
对比度:定义两个 L 或两个 Y 值之间差异的术语。对比有多种方法和标准。一种常见的方法是韦伯对比,即\Delta L / L。对比度通常以比率 (3:1) 或百分比 (70%) 表示。
对于紫色测试示例,我使用十六进制 #9d5fb0(代表 R:157、G:95、B:176),对于绿色测试示例,我使用十六进制 #318261(代表 R:49、G:130、B:97)。
function HexToRGB(hex) {
hex = String(hex);
if(hex.length==3){hex='#'+hex.substr(0, 1)+hex.substr(0, 1)+hex.substr(1, 1)+hex.substr(1, 1)+hex.substr(2, 1)+hex.substr(2, 1);}
if(hex.length==4){hex='#'+hex.substr(1, 1)+hex.substr(1, 1)+hex.substr(2, 1)+hex.substr(2, 1)+hex.substr(3, 1)+hex.substr(3, 1);}
if(hex.length==6){hex='#'+hex;}
let R = parseInt(hex.substr(1, 2),16);
let G = parseInt(hex.substr(3, 2),16);
let B = parseInt(hex.substr(5, 2),16);
console.log("rgb from "+hex+" = "+[R,G,B]);
return [R,G,B];
}
最常见的灰度程序平均方法是:
$$ 灰度=\operatorname{round}((R+G+B) / 3) $$
function RGBToGRAY(rgb) {
let avg = parseInt((rgb[0]+rgb[1]+rgb[2])/3);
return [avg,avg,avg];
}
这会将紫色变成 #8f8f8f 因为平均值 = 143,将绿色变成#5c5c5c,因为平均值 = 92。92 和 143 之间的差异太大,会错误地通过我预期的测试。
现在,正如之前所解释的,我们应该使其呈线性并应用 gamma 2.2 校正。
$$ R^{\prime \wedge} 2.2=R \operatorname{lin} G^{\prime \wedge} 2.2=G \operatorname{lin} B^{\prime \wedge} 2.2=B \operatorname{lin}
$$
function linearFromRGB(rgb) {
let R = rgb[0]/255.0;
let G = rgb[1]/255.0;
let B = rgb[2]/255.0;
let gamma = 2.2;
R = Math.pow(R, gamma);
G = Math.pow(G, gamma);
B = Math.pow(B, gamma);
let linear = [R,G,B];
console.log('linearized rgb = '+linear);
return linear;
}
紫色的伽马校正线性结果现在为 R:0.3440、G:0.1139、B:0.4423,绿色的结果为 R:0.0265、G:0.2271、B:0.1192。现在通过应用系数获得亮度 L 或(XYZ 比例的 Y)如下:
$$ Y=\text { Rlin* } 0.2126 \text { + Glin* } 0.7152+\text { Blin* } 0.0722 $$
function luminanceFromLin(rgblin) {
let Y = (0.2126 * (rgblin[0]));
Y = Y + (0.7152 * (rgblin[1]));
Y = Y + (0.0722 * (rgblin[2]));
console.log('luminance from linear = '+Y);
return Y;
}
现在两个 Y(或 L)值之间的感知对比度:
$$ \text { (L较亮 - L较暗) / (L较亮 + 0.1) } $$