【问题标题】:Convert from relative luminance to HSL从相对亮度转换为 HSL
【发布时间】:2020-08-14 22:00:18
【问题描述】:

给定 HSL 中的某种颜色(假设是 hsl(74,64%,59%)),我想计算什么较暗的阴影(具有相同的 h 和 s 值)给我足够的对比度来满足 W3C 的颜色对比度要求.

有一些公式可以将 HSL 转换为 RGB(例如 https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB)并计算该 RGB 的相对亮度(例如 https://www.w3.org/TR/WCAG20/#relativeluminancedef)。根据颜色对比公式 (https://www.w3.org/TR/WCAG20/#contrast-ratiodef),我可以计算出其他颜色的相对亮度。

但是,我被困住了。我找不到从给定的相对亮度计算回具有给定 h 和 s 的 HSL 颜色的方法。

使用https://contrast-ratio.com/ 之类的工具,我可以降低亮度直到满足要求,但我想要一个公式(最好在 JavaScript 中)对大量颜色进行计算。

(我目前正在使用二进制搜索方法来找到最接近的值,通过测试从 HSL 到 RGB 到相对亮度的许多转换,但这非常密集,而且我想知道在两者之间转换到 RGB 是否会引入不准确。)

【问题讨论】:

    标签: hsl contrast


    【解决方案1】:

    希望这是你需要的

    使用此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%)
    

    【讨论】:

    • 谢谢迈克尔,这确实回答了我的问题,尽管你基本上和我做的一样。 (我提到我正在对所需结果进行二进制搜索,而您正在以 0.01 的增量测试所有结果。)但是
    • ...但我在stackoverflow.com/a/23704612/72809 的评论中看到,如果不通过 RGB,显然无法直接计算。对您的代码的一个小注释,我要求 HSL 作为结果,因此您在 rgbFromHslContrast 末尾的行 return hslToRgb(h,s,l2); 可能只是 return [h,s,l2]。还要注意,l1 是相对亮度,而 l2 是亮度。 :)
    猜你喜欢
    • 2014-07-05
    • 2012-11-04
    • 2012-08-02
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    • 2017-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多