【问题标题】:Use Color.GetSaturation, Color.GetBrightness in Wpf在 Wpf 中使用 Color.GetSaturation、Color.GetBrightness
【发布时间】:2013-09-21 07:37:30
【问题描述】:

我正在尝试使用找到的问题的答案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 中使用建议的答案吗?

【问题讨论】:

  • 听起来您缺少参考。右键单击项目下的 References 并选择 Add Reference...
  • 感谢您的评论!正如我的问题所述,我已经添加了 System.Drawing 引用,但是当我在代码中输入 System. 时,引用 Drawing 不会出现
  • Range 有什么功能? System.Drawing.Color 没有定义该方法。您还需要转换回 WPF 颜色。
  • System.Drawing.Color msdn.microsoft.com/en-us/library/system.drawing.color.aspxSystem.Windos.Media.Color msdn.microsoft.com/en-us/library/… 中没有范围
  • @KentBoogaart 对不起,我做错了!我会更新我的问题

标签: c# wpf colors


【解决方案1】:

使用以下扩展方法:

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

【讨论】:

    【解决方案2】:

    不确定问题是什么,但我从其他 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);
            }
        }
    }
    

    【讨论】:

    • 问题是我在引用中添加了System.Drawing,但是当我在我的代码中输入System. 时,Drawing 引用没有出现。您是在 Wpf 还是 windows 窗体中使用它?
    • 我在 WPF 中使用这个
    • 感谢您的回答!您能否告诉我如何应用我在另一个问题中已经写过的示例。根据X 的值,画笔颜色会发生变化。我希望色彩变化尽可能顺利。那你能给点建议吗?
    • 另外,我已经调试过了,但是调试指针从来没有进入函数public static IEnumerable&lt;System.Drawing.Color&gt; Range(this System.Drawing.Color firstColor, System.Drawing.Color lastColor, int count, Direction hueDirection)虽然我使用了step-into,请你告诉我如何通过这个函数进入调试来检查编码并理解它?
    • 我已经使用了上面的答案,但是使用了numberOfIntermediateColors=30,但是当我运行它时,我在结果中发现了不同的颜色,而不是红色、橙色、黄色和绿色,例如蓝色、紫色。我不知道为什么会这样?下面是我的代码片段IEnumerable&lt;System.Drawing.Color&gt; colorPalette = System.Drawing.Color.Green.Range(System.Drawing.Color.Red, numberOfIntermediateColors); if (X == 21) Pen = new Pen(new SolidColorBrush(Color.FromArgb(colorPalette.ElementAt(21).A, colorPalette.ElementAt(21).R, colorPalette.ElementAt(21).G, colorPalette.ElementAt(21).B)), 6);你能告诉我吗?
    【解决方案3】:

    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>
    

    结果:

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

    【讨论】:

    • 我认为 OP 正在尝试在 2 种颜色之间创建调色板,而不是创建画笔。
    • @Sa_ddam213 啊,好的。调色板是什么意思?那到底是什么?
    • 它只是一组颜色 msdn.microsoft.com/en-us/library/… ,我认为 OP 缺少某处的扩展方法
    • @HighCore 感谢您的回答!我想要做的是应用在 WPF stackoverflow.com/questions/18821696/… 中找到的答案
    • @HighCore 我已经更新了我的问题,所以如果你可以请看一下。非常感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-17
    • 2011-08-12
    • 2013-08-08
    • 2016-07-14
    • 2017-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多