如何根据字体颜色来选择背景颜色,以获得适当的对比度

本文关键字:颜色 对比度 背景 何根 字体 选择 | 更新日期: 2023-09-27 18:02:47

我对颜色构成不太了解,所以我想出了这个算法,它会根据字体的颜色来选择背景颜色,以试错为基础:

public class BackgroundFromForegroundColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (!(value is Color))
            return value;
        Color color = (Color)value;
        if (color.R + color.G + color.B > 550)
            return new SolidColorBrush(Colors.Gray);
        else if (color.R + color.G + color.B > 400)
            return new SolidColorBrush(Colors.LightGray);
        else
            return new SolidColorBrush(Colors.White);
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

我在谷歌上搜索了一下,但是我没有找到任何非常正式的方法来计算背景颜色以获得与字体颜色的良好对比效果。

所以我的问题是:有没有一种更"正式"的方法来选择一个好的背景来获得良好的对比?或者,无论字体颜色如何,您如何处理选择背景颜色的唯一目的是使您的文本尽可能具有可读性?

快速更新

更多的上下文:我只是想展示一些文本的预览(例如"快速的棕色狐狸跳过了懒惰的狗"),其中用户选择字体颜色,粗细,字体等。然而,我很想看看能做些什么,无论是超级简单的,还是更复杂的。

最后编辑

我决定去什么H.B.建议:它似乎工作与我尝试的所有颜色都很好,不像我以前的算法,前景并不总是与背景形成正确的对比。我很想知道是否有公式可以为给定的前景提供"最佳"背景,但就我所需要的而言,黑白效果很好。这是我的代码的当前形式:

public class BackgroundFromForegroundColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (!(value is Color))
            return value;
        Color color = (Color)value;
        double Y = 0.2126 * color.ScR + 0.7152 * color.ScG + 0.0722 * color.ScB;
        return Y > 0.4 ? Brushes.Black : Brushes.White;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

如何根据字体颜色来选择背景颜色,以获得适当的对比度

有一些计算颜色亮度的方法,在此基础上,你可以选择黑色或白色的背景,你会得到一个不错的可读性。参见luma

Y = 0.2126 R + 0.7152 G + 0.0722 B

我认为阈值将是0.5,如果你使用标准化的输入值(0.0 - 1.0),但它已经有一段时间,因为我使用这个…

编辑:示例转换实现草图:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    var c = (Color)value;
    var l = 0.2126 * c.ScR + 0.7152 * c.ScG + 0.0722 * c.ScB;
    return l < 0.5 ? Brushes.White : Brushes.Black;
}

阈值实际上可能有点依赖于显示和个人偏好,我更喜欢低一些,导致黑色背景的更大份额。

我认为这不仅仅是一个设计问题,而不是一个"正式"的方式。所以这是你自己的决定。你能举几个接近你想要达到的目标的例子吗?我也工作在类似于你的问题这些天(创建在线画廊改变BG根据颜色的照片画廊动态),我想我会很好,我的建议是,不管你选择作为背景,只是产生一层黑色或白色的背景下,根据您的前景颜色相反(亮度),这样你在某种意义上"限制"BG,例如BG可以设置为黑色,你的文字也是黑色的,但在BG的顶部有一个白色的图层,使文字可读。图层的不透明度留给你,试着看看什么是最好的值。你可以在数值转换器中实现这一切,并且BG +"图层"合成只不过是一个颜色值。

任何给定颜色c中最具对比性(不同)的颜色

new Color(c.R > .5 ? 0 : 1, c.G > .5 ? 0 : 1, c.B > .5 ? 0 : 1)

或者如果需要0-255范围

new Color(c.R > 127 ? 0 : 255, c.G > 127 ? 0 : 255, c.B > 127 ? 0 : 255)

文本在给定背景上的可见性总是最好的,但并不总是很好。如果你不想被疯狂的颜色打扰,你只需要使用公认的答案建议的黑色/白色。

在我工作的一个项目中,我们决定使用一个公式,通过红绿蓝值分离颜色,并从255减去红绿蓝,以获得近乎完美的对比色。

然而

…灰色是不适合这个公式的颜色之一。在做减法之前,你可以简单地检查一下颜色是否为灰色。在光谱的两端还有一些其他的颜色,你可能需要握住它们的手才能得到一个可读的对比颜色。