簡體   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