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

匆匆过客 提交于 2019-12-23 07:28:45

问题


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 ?


回答1:


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:

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



回答2:


Let's say you're using a slider with a minimum value of 1 and 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.

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.Maximum with 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 red being 0, so you can add a minimum there value if you don't want the red component to be that low.




回答3:


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

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.




回答4:


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

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

It would look like:

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

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




回答5:


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


来源:https://stackoverflow.com/questions/12894605/how-to-make-specific-color-darken-or-lighten-based-on-value-in-wpf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!