如何根据 wpf 中的值使特定颜色变暗或变亮?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12894605/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 05:46:59  来源:igfitidea点击:

How to make specific color darken or lighten based on value in wpf?

c#wpfcolorssystem.windows.media

提问by Shailesh Jaiswal

I am developing wpf application. I am having the instance of Color object in C#. Suppose I have instance of red Color object i.e. Color c = Color.FromArgb(255,255,0,0)Now suppose that I have one value which ranges from 1 to 10. So based on this value I want to change the color of the 'c' object. I want light red for 1 and dark red for 10. The light red becomes the dark as the value increases from 1. How can I do this in C# for wpf application ? Can you please provide me any code or link through which I can resolve the above issue ?

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

回答by Nikolay Khil

You can try to simply multiply red, green and blue components by some coefficient.

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

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

Or, if you'd like to use an integer value from 1 to 10 instead of the coefficient:

或者,如果您想使用 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));
}

回答by Pyritie

What about a Style DataTrigger, if you have a set number of values?

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

https://www.google.co.uk/search?q=c%23+wpf+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>

Then if you need to reuse the style then you could put in the <Resources>section of your window/usercontrol.

然后,如果您需要重用样式,则可以将其放入<Resources>窗口/用户控件的部分。

回答by keyboardP

Let's say you're using a slider with a minimum value of 1and a maximum value of 10. You can just multiply the value by 25.5 (255 / max value). Then, subtract that answer from max value (255) and use that as the red value.

假设您使用的滑块的最小值为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)

You can replace 255 / slider.Maximumwith a constant value since it will likely remain the same. The formula above will create an inverse effect, so the lower the slider value, the brighter the shade of red. Of course, a value of 10 will result in redbeing 0, so you can add a minimum there value if you don't want the red component to be that low.

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

回答by Louis Kottmann

A cleaner solution would be to juxtapose 2 rectangles: one is the color you want, the other is black.

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

Then play with Opacityon the black rectangle to darken/lighten the underlying color.

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

It would look like:

它看起来像:

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

Of course, colorModifierPercentagemust be a number between 0 and 1, and rectangle can be any Shape.

当然,colorModifierPercentage必须是 0 到 1 之间的数字,而 rectangle 可以是任何Shape

回答by Laila

There is an article about it at CodeProject:

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