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

发布于 2024-11-25 09:33:11 字数 1830 浏览 2 评论 0原文

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

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

我对此进行了一些谷歌搜索,但我还没有找到任何东西正式介绍计算背景颜色以获得与字体颜色良好对比效果的不同方法。

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

快速更新

更多上下文:我只是想显示一些文本的预览(例如“快速的棕色狐狸跳过懒狗”),用户可以在其中选择字体颜色、粗细、然而,我有兴趣看看可以做什么,无论它是超级简单还是更复杂。

最终编辑

我决定采用HB的建议:它似乎适用于我尝试过的所有颜色,与我之前的算法不同,前景并不总是与前景形成正确的对比背景。我很想知道是否有公式可以为给定的前景提供“最佳”背景,但对于我需要的黑/白效果就很好。这是我当前形式的代码:

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

I don't know much about color composition, so I came up with this algorithm that will pick a background color based on the font color on a trial an errors basis:

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

I did some googling about this, but I haven't found anything very formal about the different ways a background color can be calculated to get a good contrast effect with the font color.

So my question is: is there a more "formal" approach to pick a good background to get a good contrast? Alternatively, how would you handle picking a background color with the sole intent of having your text as readable as possible whatever its font color?

Quick update

A bit more context: I'm simply trying to show a preview of some text (eg "The quick brown fox jumps over the lazy dog") where the user picks the font color, weight, font, etc. I am however interested to see what can be done, whether it's super simple, or more complex.

Final edit

I decided to go with what H.B. suggested: it seems to work fine with all colors I tried unlike with my previous algorithm were the foreground would not always contrast properly with the background. I would've been curious to see if there is formula that gives you an "optimal" background for a given foreground, but for what I need black/white works just fine. This is my code in its current form:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

泅渡 2024-12-02 09:33:11

有一些计算颜色亮度的方法,基于此,您只需采用黑色或白色背景即可获得不错的可读性。例如,请参阅 luma

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

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

There are some methods of calculating the brightness of a colour, based on that you could just take a black or white background and you would get a decent readability. See luma for example

Y = 0.2126 R + 0.7152 G + 0.0722 B

I think the threshold would be 0.5 if you use normalized input values (0.0 - 1.0), but it's been a while since i used this...

Edit: Example convert implementation sketch:

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

The threshold may actually be a bit dependent on the display and personal preference, i for one would prefer something lower resulting in a bigger share of black backgrounds.

情何以堪。 2024-12-02 09:33:11

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

则最具对比(不同)的颜色给定背景上的文本可见性始终是最好的,但并不总是很好。如果您不想被疯狂的颜色打扰,您最终会使用已接受答案建议的黑/白。

The most contrasting (different) color for any given color c you simply get by

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

or if you need 0-255 range

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

That text visibility on given background is allways the best, but not allways nice. In case you do not want to disturbe by crazy colors you just end up using black/white suggested by accepted answer.

淡忘如思 2024-12-02 09:33:11

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

I think this is more than a design issue than having a 'formal' way. So it is a bit to your own decision. Can you show up some examples close to what you are tring to achieve? I am also working on something similar to your problem these days (creating online gallery which changes its BG according to the colors in the photos in the gallery dynamically), and I think I'm going pretty well, my advice is that, whatever you choose as a background, just create a layer of black or white in the background, depending on your foreground color (opposite brightness of it), and that way you are in a sense 'limiting' the BG, e.g. BG could be set to black, and your text is black too, but there's a white layer on top of BG that makes the text readable. The opacity of the layer is left to you, try and see what is the best value. And you can implement the whole thing in the value converter, and that BG + 'layer' composition is nothing more than a color value.

笨死的猪 2024-12-02 09:33:11

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

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

In a project I work on we decided on a formula that seperates the color by Red Green Blue values and subtract Red Green and Blue from 255 to get a near perfect constrasting color.

However...Gray is one of those colors that wouldn't work with this formula. You can simple check to see if the color is Gray before doing the subtraction. There are some other colors on both ends of the color spectrume where you might have to hold their hand to get a readable constrasting color.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文