【问题标题】:How to make specific color darken or lighten based on value in wpf?如何根据 wpf 中的值使特定颜色变暗或变亮?
【发布时间】:2012-10-05 08:48:13
【问题描述】:

我正在开发 wpf 应用程序。我在 C# 中有 Color 对象的实例。假设我有一个红色颜色对象的实例,即Color c = Color.FromArgb(255,255,0,0) 现在假设我有一个值,范围从 1 到 10。所以基于这个值,我想更改“c”对象的颜色。我想要 1 为浅红色,10 为深红色。随着值从 1 增加,浅红色变为深色。如何在 C# 中为 wpf 应用程序执行此操作?您能否提供我可以解决上述问题的任何代码或链接?

【问题讨论】:

    标签: c# wpf colors system.windows.media


    【解决方案1】:

    您可以尝试简单地将红色、绿色和蓝色分量乘以某个系数。

    public static Color ChangeLightness(this Color color, float coef)
    {
        return Color.FromArgb((int)(color.R * coef), (int)(color.G * coef),
            (int)(color.B * coef));
    }
    

    或者,如果您想使用 1 到 10 之间的整数值而不是系数:

    private const int MinLightness = 1;
    private const int MaxLightness = 10;
    private const float MinLightnessCoef = 1f;
    private const float MaxLightnessCoef = 0.4f;
    
    public static Color ChangeLightness(this Color color, int lightness)
    {
        if (lightness < MinLightness)
            lightness = MinLightness;
        else if (lightness > MaxLightness)
            lightness = MaxLightness;
    
        float coef = MinLightnessCoef +
          (
            (lightness - MinLightness) *
              ((MaxLightnessCoef - MinLightnessCoef) / (MaxLightness - MinLightness))
          );
    
        return Color.FromArgb(color.A, (int)(color.R * coef), (int)(color.G * coef),
            (int)(color.B * coef));
    }
    

    【讨论】:

    • 哪个系数?我应该传递什么作为 coef ?
    • coef 是一个从 0 到 1 的值;越多越亮,越少越暗;
    • @NikolayKhil 我正在尝试这段代码,但它给出了这个错误“方法'FromArgb'没有重载需要3个参数”,因为没有传递Alpha通道。能否请教一下
    • 第一个条目不正确,应该使用“FromRgb” - 此外,值需要转换为字节。
    • 啊——好吧,我的错。事实上,.NET 中有两种不同的“颜色”- 类。 Nikolay 指的是 System.Drawing,我指的是 System.Windows.Media - 哦,微软... .
    【解决方案2】:

    如果您有一定数量的值,那么 Style DataTrigger 怎么样?

    https://www.google.co.uk/search?q=c%23+wpf+style+datatrigger

    <Button>
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding NameOfYourProperty}" Value="0">
                        <Setter Property="Background"
                                Value="#FF000000" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding NameOfYourProperty}" Value="1">
                        <Setter Property="Background"
                                Value="#FF110000" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding NameOfYourProperty}" Value="2">
                        <Setter Property="Background"
                                Value="#FF220000" />
                    </DataTrigger>
                    ( etc ... )
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>
    

    然后,如果您需要重用该样式,则可以放入窗口/用户控件的&lt;Resources&gt; 部分。

    【讨论】:

    • 我认为你应该阅读the following thread
    • 抱歉,我忘了我现在可以添加 cmets - 应该将它作为一个发布。我改进了这个答案
    【解决方案3】:

    假设您使用的滑块最小值为1,最大值为10。您可以将该值乘以25.5 (255 / max value)。然后,从最大值 (255) 中减去该答案并将其用作红色值。

    double newRedValue = 255 - (slider.Value * (255 / slider.Maximum));
    int redValue = Convert.ToInt32(newRedValue);
    Color c = Color.FromArgb(redValue ,255,0,0)
    

    您可以将255 / slider.Maximum 替换为常数值,因为它可能会保持不变。上面的公式将产生相反的效果,因此滑块值越低,红色阴影越亮。当然,值 10 将导致 red 变为 0,因此如果您不希望红色分量那么低,可以添加一个最小值。

    【讨论】:

      【解决方案4】:

      更简洁的解决方案是将 2 个矩形并置:一个是您想要的颜色,另一个是黑色。

      然后在黑色矩形上使用Opacity 来调暗/调亮底层颜色。

      看起来像:

      <Grid>
         <Rectangle Fill="{Binding myColor}" />
         <Rectangle Fill="Black" Opacity="{Binding colorModifierPercentage}" />
      </Grid>
      

      当然,colorModifierPercentage 必须是 0 到 1 之间的数字,矩形可以是任意的Shape

      【讨论】:

        【解决方案5】:

        an article about it at CodeProject

            /// <summary>
            /// Converts a WPF RGB color to an HSL color
            /// </summary>
            /// <param name="rgbColor">The RGB color to convert.</param>
            /// <returns>An HSL color object equivalent to the RGB color object passed in.</returns>
            static HlsColor RgbToHls(Color rgbColor)
            {
                // Initialize result
                var hlsColor = new HlsColor();
        
                // Convert RGB values to percentages
                double r = (double)rgbColor.R / 255;
                var g = (double)rgbColor.G / 255;
                var b = (double)rgbColor.B / 255;
                var a = (double)rgbColor.A / 255;
        
                // Find min and max RGB values
                var min = Math.Min(r, Math.Min(g, b));
                var max = Math.Max(r, Math.Max(g, b));
                var delta = max - min;
        
                /* If max and min are equal, that means we are dealing with 
                 * a shade of gray. So we set H and S to zero, and L to either
                 * max or min (it doesn't matter which), and  then we exit. */
        
                //Special case: Gray
                if (max == min)
                {
                    hlsColor.H = 0;
                    hlsColor.S = 0;
                    hlsColor.L = max;
                    return hlsColor;
                }
        
                /* If we get to this point, we know we don't have a shade of gray. */
        
                // Set L
                hlsColor.L = (min + max) / 2;
        
                // Set S
                if(hlsColor.L < 0.5)
                {
                    hlsColor.S = delta / (max + min);
                }
                else
                {
                    hlsColor.S = delta / (2.0 - max - min);
                }
        
                // Set H
                if (r == max) hlsColor.H = (g - b) / delta;
                if (g == max) hlsColor.H = 2.0 + (b - r) / delta;
                if (b == max) hlsColor.H = 4.0 + (r - g) / delta;
                hlsColor.H *= 60;
                if (hlsColor.H < 0) hlsColor.H += 360;
        
                // Set A
                hlsColor.A = a;
        
                // Set return value
                return hlsColor;
        
            }
        
            /// <summary>
            /// Converts a WPF HSL color to an RGB color
            /// </summary>
            /// <param name="hlsColor">The HSL color to convert.</param>
            /// <returns>An RGB color object equivalent to the HSL color object passed in.</returns>
            static Color HlsToRgb(HlsColor hlsColor)
            {
                // Initialize result
                var rgbColor = new Color();
        
                /* If S = 0, that means we are dealing with a shade 
                 * of gray. So, we set R, G, and B to L and exit. */
        
                // Special case: Gray
                if (hlsColor.S == 0)
                {
                    rgbColor.R = (byte)(hlsColor.L  * 255);
                    rgbColor.G = (byte)(hlsColor.L * 255);
                    rgbColor.B = (byte)(hlsColor.L * 255);
                    rgbColor.A = (byte)(hlsColor.A * 255);
                    return rgbColor;
                }
        
                double t1;
                if (hlsColor.L < 0.5)
                {
                    t1 = hlsColor.L*(1.0 + hlsColor.S);
                }
                else
                {
                    t1 = hlsColor.L + hlsColor.S - (hlsColor.L * hlsColor.S);
                }
        
                var t2 = 2.0*hlsColor.L - t1;
        
                // Convert H from degrees to a percentage
                var h = hlsColor.H / 360;
        
                // Set colors as percentage values
                var tR = h + (1.0/3.0);
                var r = SetColor(t1, t2, tR);
        
                var tG = h;
                var g = SetColor(t1, t2, tG);
        
                var tB = h - (1.0 / 3.0);
                var b = SetColor(t1, t2, tB);
        
                // Assign colors to Color object
                rgbColor.R = (byte)(r * 255);
                rgbColor.G = (byte)(g * 255);
                rgbColor.B = (byte)(b * 255);
                rgbColor.A = (byte)(hlsColor.A * 255);
        
                // Set return value
                return rgbColor;
            }
        
            /// <summary>
            /// Used by the HSL-to-RGB converter.
            /// </summary>
            /// <param name="t1">A temporary variable.</param>
            /// <param name="t2">A temporary variable.</param>
            /// <param name="t3">A temporary variable.</param>
            /// <returns>An RGB color value, in decimal format.</returns>
            private static double SetColor(double t1, double t2, double t3)
            {
                if (t3 < 0) t3 += 1.0;
                if (t3 > 1) t3 -= 1.0;
        
                double color;
                if (6.0 * t3 < 1)
                {
                    color = t2 + (t1 - t2) * 6.0 * t3;
                }
                else if(2.0 * t3 < 1)
                {
                    color = t1;
                }
                else if(3.0*t3 < 2)
                {
                    color = t2 + (t1 - t2) * ((2.0/3.0) - t3) * 6.0;
                }
                else
                {
                    color = t2;
                }
        
                // Set return value
                return color;
            }
        

        【讨论】:

          猜你喜欢
          • 2016-10-12
          • 2020-06-09
          • 2017-12-27
          • 2013-01-09
          • 2013-08-18
          • 2020-04-04
          • 2021-08-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多