从相对亮度转换为 HSL
Convert from relative luminance to HSL
给定 HSL 中的某种颜色(假设 hsl(74,64%,59%)),我想计算什么较深的阴影(具有相同的 h 和 s 值)给我足够的对比度以满足 W3C 颜色对比度要求。
有将 HSL 转换为 RGB 的公式(例如 https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB) and to calculate the relative luminance from that RGB (for example https://www.w3.org/TR/WCAG20/#relativeluminancedef). Based on the color contrast formula (https://www.w3.org/TR/WCAG20/#contrast-ratiodef)我可以计算出我的其他颜色的相对亮度应该是多少。
然而,我被卡住了。我发现无法从给定的相对亮度计算回具有给定 h 和 s 的 HSL 颜色。
使用像 https://contrast-ratio.com/ 这样的工具我可以降低亮度直到它满足要求,但我想要一个公式(最好在 JavaScript 中)来为大量选择的颜色做这个计算.
(我目前正在使用二进制搜索方法找到最接近的值,通过测试从 HSL 到 RGB 再到相对亮度的许多转换,但这相当密集,而且我想知道转换到 RGB 之间是否会引入不准确。 )
希望这是你需要的
使用此 SO answer 及以下公式:
// Relative luminance calculations
function adjustGamma(p) {
if (p <= 0.03928) {
return p / 12.92;
} else {
return Math.pow( ( p + 0.055 ) / 1.055, 2.4 );
}
}
function relativeLuminance(rgb) {
const r = adjustGamma( rgb[0] / 255 );
const g = adjustGamma( rgb[1] / 255 );
const b = adjustGamma( rgb[2] / 255 );
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}
// Contrast calculations
function contrastRatio(a,b) {
const ratio = (a + 0.05) / (b + 0.05);
return ratio >= 1 ? ratio : 1 / ratio;
}
// Loop for correct lightness
function rgbFromHslContrast(h, s, l1, ratio) {
var inc = -0.01;
var l2 = ( ( l1 + 0.05 ) / ratio - 0.05 );
if (l2 < 0) {
l2 = ( ratio * ( l1 + 0.05 ) - 0.05 );
inc = -inc;
}
while (contrastRatio(l1, relativeLuminance(hslToRgb(h, s, l2))) < ratio) {
l2 += inc;
}
return hslToRgb(h, s, l2);
}
您要调用的函数是:
const originalHslAsRgb = hslToRgb(0.2, 0.2, 0.2);
const l1 = relativeLuminance(originalHslAsRgb);
const contrastRgb = rgbFromHslContrast(0.2, 0.2, l1, 3.5) // 3.5 is minimum contrast factor we target for..
// [139, 149, 100]
// equivalent to hsl(72, 20%, 53%)
给定 HSL 中的某种颜色(假设 hsl(74,64%,59%)),我想计算什么较深的阴影(具有相同的 h 和 s 值)给我足够的对比度以满足 W3C 颜色对比度要求。
有将 HSL 转换为 RGB 的公式(例如 https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB) and to calculate the relative luminance from that RGB (for example https://www.w3.org/TR/WCAG20/#relativeluminancedef). Based on the color contrast formula (https://www.w3.org/TR/WCAG20/#contrast-ratiodef)我可以计算出我的其他颜色的相对亮度应该是多少。
然而,我被卡住了。我发现无法从给定的相对亮度计算回具有给定 h 和 s 的 HSL 颜色。
使用像 https://contrast-ratio.com/ 这样的工具我可以降低亮度直到它满足要求,但我想要一个公式(最好在 JavaScript 中)来为大量选择的颜色做这个计算.
(我目前正在使用二进制搜索方法找到最接近的值,通过测试从 HSL 到 RGB 再到相对亮度的许多转换,但这相当密集,而且我想知道转换到 RGB 之间是否会引入不准确。 )
希望这是你需要的
使用此 SO answer 及以下公式:
// Relative luminance calculations
function adjustGamma(p) {
if (p <= 0.03928) {
return p / 12.92;
} else {
return Math.pow( ( p + 0.055 ) / 1.055, 2.4 );
}
}
function relativeLuminance(rgb) {
const r = adjustGamma( rgb[0] / 255 );
const g = adjustGamma( rgb[1] / 255 );
const b = adjustGamma( rgb[2] / 255 );
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}
// Contrast calculations
function contrastRatio(a,b) {
const ratio = (a + 0.05) / (b + 0.05);
return ratio >= 1 ? ratio : 1 / ratio;
}
// Loop for correct lightness
function rgbFromHslContrast(h, s, l1, ratio) {
var inc = -0.01;
var l2 = ( ( l1 + 0.05 ) / ratio - 0.05 );
if (l2 < 0) {
l2 = ( ratio * ( l1 + 0.05 ) - 0.05 );
inc = -inc;
}
while (contrastRatio(l1, relativeLuminance(hslToRgb(h, s, l2))) < ratio) {
l2 += inc;
}
return hslToRgb(h, s, l2);
}
您要调用的函数是:
const originalHslAsRgb = hslToRgb(0.2, 0.2, 0.2);
const l1 = relativeLuminance(originalHslAsRgb);
const contrastRgb = rgbFromHslContrast(0.2, 0.2, l1, 3.5) // 3.5 is minimum contrast factor we target for..
// [139, 149, 100]
// equivalent to hsl(72, 20%, 53%)