18

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

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();
    }
}
4

4 回答 4

20

有一些计算颜色亮度的方法,基于这些方法,您可以只取黑色或白色背景,并且可以获得不错的可读性。亮度为例

Y = 0.2126 R + 0.7152 G + 0.0722 B

如果您使用标准化输入值(0.0 - 1.0),我认为阈值将是 0.5,但自从我使用它已经有一段时间了......

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

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;
}

阈值实际上可能有点取决于显示器和个人偏好,我会更喜欢较低的东西,从而导致黑色背景的份额更大。

于 2011-07-20T14:11:50.047 回答
3

我认为这不仅仅是一个设计问题,而不是一个“正式”的方式。所以这有点取决于你自己的决定。你能展示一些接近你想要达到的目标的例子吗?这些天我也在处理与您的问题类似的事情(创建在线画廊,根据画廊中照片中的颜色动态更改其 BG),我认为我进展得很好,我的建议是,无论你选择作为背景,只需在背景中创建一层黑色或白色,具体取决于您的前景色(与它相反的亮度),这样您在某种意义上“限制”了 BG,例如 BG 可以设置为黑色,并且您的文本也是黑色的,但是 BG 顶部有一个白色层,使文本可读。图层的不透明度由您决定,尝试看看什么是最佳值。

于 2011-07-20T14:02:57.480 回答
3

任何给定颜色 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)

给定背景上的文本可见性总是最好的,但并不总是很好。如果您不想被疯狂的颜色打扰,您最终只能使用接受的答案建议的黑色/白色。

于 2016-09-01T17:49:33.320 回答
1

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

但是...灰色是不适用于此公式的颜色之一。在进行减法之前,您可以简单地检查颜色是否为灰色。在色谱的两端还有一些其他颜色,您可能必须握住他们的手才能获得可读的对比色。

于 2011-07-20T14:05:19.913 回答