在Wpf中使用Color.GetSaturation,Color.GetBrightness

时间:2013-09-17 01:57:31

标签: c# wpf colors

我正在尝试使用here问题的答案 我在使用颜色类时遇到问题。例如,Color.Red.Range(Color.Green, numberOfIntermediateColors);出现错误,说“'System.Windows.Media.Color'不包含'Red'的定义” 与GetBrightnessGetSaturationGetHue相同,有一个错误说“'System.Windows.Media.Color'不包含'GetSaturation'的定义,也没有扩展方法'GetSaturation'接受第一个类型为'System.Windows.Media.Color'的参数可以找到(你是否缺少using指令或汇编引用?)“

那么任何人都可以请问如何在Wpf中使用建议的答案?

3 个答案:

答案 0 :(得分:8)

使用以下扩展方法:

public static float GetHue(this System.Windows.Media.Color c) =>
  System.Drawing.Color.FromArgb(c.A, c.R, c.G, c.B).GetHue();

public static float GetBrightness(this System.Windows.Media.Color c) =>
  System.Drawing.Color.FromArgb(c.A, c.R, c.G, c.B).GetBrightness();

public static float GetSaturation(this System.Windows.Media.Color c) =>
  System.Drawing.Color.FromArgb(c.A, c.R, c.G, c.B).GetSaturation();

答案 1 :(得分:2)

WPF不关心System.Drawing。从项目中删除该引用。

您要找的是LinearGradientBrush

<Border>
    <Border.Background>
        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
            <GradientStop Color="Green" Offset="0"/>
            <GradientStop Color="Red" Offset="1"/>
        </LinearGradientBrush>
    </Border.Background>
</Border>

结果:

enter image description here

请,请不要使用程序代码来定义您的UI。这就是XAML的用途。

答案 2 :(得分:1)

不确定问题是什么,但是我从其他2个答案中复制了代码,如果添加System.Drawing命名空间并修复歧义,它似乎工作正常

int numberOfIntermediateColors = 8;
IEnumerable<System.Drawing.Color> colorPalette = System.Drawing.Color.Red.Range(System.Drawing.Color.Green, numberOfIntermediateColors);
// returns 8 colors in that range.

范围扩展方法

public static class ColorExtensions
{
    public static IEnumerable<System.Drawing.Color> Range(this System.Drawing.Color firstColor, System.Drawing.Color lastColor, int count)
    {
        float stepHueClockwise = GetStepping(firstColor.GetHue(), lastColor.GetHue(), count, Direction.Clockwise);
        float stepHueCounterClockwise = GetStepping(firstColor.GetHue(), lastColor.GetHue(), count, Direction.CounterClockwise);

        if (Math.Abs(stepHueClockwise) >= Math.Abs(stepHueCounterClockwise))
            return Range(firstColor, lastColor, count, Direction.Clockwise);
        else
            return Range(firstColor, lastColor, count, Direction.CounterClockwise);
    }

    public static IEnumerable<System.Drawing.Color> Range(this System.Drawing.Color firstColor, System.Drawing.Color lastColor, int count, Direction hueDirection)
    {
        var color = firstColor;

        if (count <= 0)
            yield break;

        if (count == 1)
            yield return firstColor;

        float startingHue = color.GetHue();
        float stepHue = GetStepping(firstColor.GetHue(), lastColor.GetHue(), count - 1, hueDirection);
        var stepSaturation = (lastColor.GetSaturation() - firstColor.GetSaturation()) / (count - 1);
        var stepBrightness = (lastColor.GetBrightness() - firstColor.GetBrightness()) / (count - 1);
        var stepAlpha = (lastColor.A - firstColor.A) / (count - 1.0);

        for (int i = 1; i < count; i++)
        {
            yield return color;

            var hueValue = startingHue + stepHue * i;

            if (hueValue > 360)
                hueValue -= 360;

            if (hueValue < 0)
                hueValue = 360 + hueValue;

            color = FromAhsb(
                        Clamp((int)(color.A + stepAlpha), 0, 255),
                             hueValue,
                             Clamp(color.GetSaturation() + stepSaturation, 0, 1),
                             Clamp(color.GetBrightness() + stepBrightness, 0, 1));
        }

        yield return lastColor;
    }

    public enum Direction
    {
        Clockwise = 0,
        CounterClockwise = 1
    }

    private static float GetStepping(float start, float end, int count, Direction direction)
    {
        var hueDiff = end - start;

        switch (direction)
        {
            case Direction.CounterClockwise:
                if (hueDiff >= 0)
                    hueDiff = (360 - hueDiff) * -1;
                break;

            default:
                if (hueDiff <= 0)
                    hueDiff = 360 + hueDiff;
                break;
        }

        return hueDiff / count;
    }

    private static int Clamp(int value, int min, int max)
    {
        if (value < min)
            return min;

        if (value > max)
            return max;

        return value;
    }

    private static float Clamp(float value, float min, float max)
    {
        if (value < min)
            return min;

        if (value > max)
            return max;

        return value;
    }

    public static System.Drawing.Color FromAhsb(int alpha, float hue, float saturation, float brightness)
    {
        if (0 > alpha
            || 255 < alpha)
        {
            throw new ArgumentOutOfRangeException(
                "alpha",
                alpha,
                "Value must be within a range of 0 - 255.");
        }

        if (0f > hue
            || 360f < hue)
        {
            throw new ArgumentOutOfRangeException(
                "hue",
                hue,
                "Value must be within a range of 0 - 360.");
        }

        if (0f > saturation
            || 1f < saturation)
        {
            throw new ArgumentOutOfRangeException(
                "saturation",
                saturation,
                "Value must be within a range of 0 - 1.");
        }

        if (0f > brightness
            || 1f < brightness)
        {
            throw new ArgumentOutOfRangeException(
                "brightness",
                brightness,
                "Value must be within a range of 0 - 1.");
        }

        if (0 == saturation)
        {
            return System.Drawing.Color.FromArgb(
                                alpha,
                                Convert.ToInt32(brightness * 255),
                                Convert.ToInt32(brightness * 255),
                                Convert.ToInt32(brightness * 255));
        }

        float fMax, fMid, fMin;
        int iSextant, iMax, iMid, iMin;

        if (0.5 < brightness)
        {
            fMax = brightness - (brightness * saturation) + saturation;
            fMin = brightness + (brightness * saturation) - saturation;
        }
        else
        {
            fMax = brightness + (brightness * saturation);
            fMin = brightness - (brightness * saturation);
        }

        iSextant = (int)Math.Floor(hue / 60f);
        if (300f <= hue)
        {
            hue -= 360f;
        }

        hue /= 60f;
        hue -= 2f * (float)Math.Floor(((iSextant + 1f) % 6f) / 2f);
        if (0 == iSextant % 2)
        {
            fMid = (hue * (fMax - fMin)) + fMin;
        }
        else
        {
            fMid = fMin - (hue * (fMax - fMin));
        }

        iMax = Convert.ToInt32(fMax * 255);
        iMid = Convert.ToInt32(fMid * 255);
        iMin = Convert.ToInt32(fMin * 255);

        switch (iSextant)
        {
            case 1:
                return System.Drawing.Color.FromArgb(alpha, iMid, iMax, iMin);
            case 2:
                return System.Drawing.Color.FromArgb(alpha, iMin, iMax, iMid);
            case 3:
                return System.Drawing.Color.FromArgb(alpha, iMin, iMid, iMax);
            case 4:
                return System.Drawing.Color.FromArgb(alpha, iMid, iMin, iMax);
            case 5:
                return System.Drawing.Color.FromArgb(alpha, iMax, iMin, iMid);
            default:
                return System.Drawing.Color.FromArgb(alpha, iMax, iMid, iMin);
        }
    }
}