繁体   English   中英

从颜色列表中,如何获得同时在每种颜色上可见的浅色或深色?

[英]From a list of colors, how can I get a light or dark color that is visible over each color simultaneously?

在我的应用程序中,我允许用户最多选择三种颜色用作“主题颜色”。 这些颜色在状态栏下显示为LinearGradientBrush (如果选择一种颜色,则显示为SolidColorBrush )。 我需要状态栏前景色为浅色或深色(不一定只有黑色或白色)。 这将比仅确定应使用白色还是黑色要复杂得多,但是要包括深灰色(例如,如果用户选择主题使用白色和黑色,即是我目前的算法选择黑色作为前景,这是不可见的)之类的颜色。他们选择的黑色)。 另外, StatusBar.ForegroundColor忽略Alpha通道,因此我不能只更改不透明度。 我怎样才能做到这一点?

谢谢

对比色可以通过HSB颜色的色来确定

仅适用于黑白,您可以使用

ForeColor = BackColor.GetBrightness() > 0.4 ? Color.Black : Color.White;

您可以根据颜色的R,G和B值计算颜色的亮度,然后根据该值选择画笔。 我使用以下转换器选择与绑定的背景色形成对比的前景色。

public class ColorConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, string language)
    {
        Color c = (Color)value;
        int brightness = (int)(c.R * 0.30 + c.G * 0.59 + c.B * 0.11);
        if (brightness < 127)
            return App.Current.Resources["LightBrush"];
        else
            return App.Current.Resources["DarkBrush"];
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

我将其用于绑定到Colors类中所有已命名颜色的颜色选择器。 如果您仅针对几种主题色,则可以手工制作一张仍保持对比度的有色表,而不是将所有内容强制设置为黑白。

对于更多颜色,您可以尝试从RGB转换为HSL,在保持色相的同时修改亮度,然后再转换回去,但这可能比它值得的麻烦更多,并且在往返旅行时可能会用尽色域并获得较差的结果。

几年前, 为类似的问题创建了一些东西 ,例如给定一种颜色,它将返回与色轮相反的颜色

我用它来创建第二个或互补的彩色笔刷,以用于应用程序中,在这些应用程序中,我不仅需要单一的,用户选择的,系统范围内的强调色,还希望确保这些颜色能够一起使用而不发生冲突。

也许您可以将此想法扩展为三种颜色。

该代码在GitHub上: https : //github.com/mrlacey/WPMisc/blob/master/AccentComplimentBrush.cs

我玩了一些游戏,我认为我有一个完美的方法。 我从这个问题开始使用一种算法,然后将其与Matt Lacey和Rob Caplan的答案中的类似代码混合,将其清理并修改为可使用的颜色列表。 我认为效果很好。

private static Color DetermineForegroundColor(List<Color> colors) {
            double r = 0, g = 0, b = 0;
            foreach (Color color in colors) {
                r += color.R;
                g += color.G;
                b += color.B;
            }
            if (r > g && r > b) {
                Debug.WriteLine("First condition matched ({0}, {1}, {2})", (byte)r, (byte)g, (byte)b);
                return new Color() {
                    R = (byte)r,
                    G = (byte)r,
                    B = (byte)r
                };
            }
            else if (g > r && g > b) {
                Debug.WriteLine("Second condition matched ({0}, {1}, {2})", (byte)r, (byte)g, (byte)b);
                return new Color() {
                    R = (byte)g,
                    G = (byte)g,
                    B = (byte)g
                };
            }
            else if (b > r && b > g) {
                Debug.WriteLine("Third condition matched ({0}, {1}, {2})", (byte)r, (byte)g, (byte)b);
                return new Color() {
                    R = (byte)b,
                    G = (byte)b,
                    B = (byte)b
                };
            }
            else if (r == g) {
                Debug.WriteLine("Fourth condition matched ({0}, {1}, {2})", (byte)r, (byte)g, (byte)b);
                return new Color() {
                    R = (byte)b,
                    G = (byte)b,
                    B = (byte)b
                };
            }
            else if (r == b) {
                Debug.WriteLine("Fifth condition matched ({0}, {1}, {2})", (byte)r, (byte)g, (byte)b);
                return new Color() {
                    R = (byte)g,
                    G = (byte)g,
                    B = (byte)g
                };
            }
            else if (g == b) {
                Debug.WriteLine("Sixth condition matched ({0}, {1}, {2})", (byte)r, (byte)g, (byte)b);
                return new Color() {
                    R = (byte)r,
                    G = (byte)r,
                    B = (byte)r
                };
            }
            else {
                Debug.WriteLine("No condition matched ({0}, {1}, {2})", (byte)r, (byte)g, (byte)b);
                return new Color() {
                    R = 255,
                    G = 255,
                    B = 255
                };
            }
        }

将来,我可能会用switch/case块替换较大的if/else-if/else块,以减少体积。

尝试以下任一方法:

  • 反转每个RGB值,然后可能将其调整为一组预定义颜色中最接近的颜色。

要么

  • 或将RGB的每个值乘以给定的数量(例如.25-.5)。 如果> 128,则相乘,然后相减两次;如果<128,则相乘。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM