我如何在C#中获得彩虹色渐变?

20

我希望基于彩虹的颜色(红色...黄色...绿色...蓝色...)有一个颜色枚举。

我基本上看到了两种方法:

  1. 创建一个包含一些重要参考颜色并在这些颜色之间进行插值的查找表。我一点也不喜欢这个想法。

  2. 应用一些更或少花哨的数学算法。也许是少,但我不太清楚它的工作原理。有什么想法吗?

(哦,当我进行了一些 Stack Overflow 的搜索时,我发现没有好的结果。如果此问题已经发布,请只指向该位置,我会删除这个问题。)

编辑:我希望这与用于显示渐变的技术无关。例如,GetRainbowColor(float f),其中f从0(红色)到1(紫色)的范围将非常有效。


1
WPF?WinForms?ASP.NET?答案可能会根据技术不同而改变。 - Mike Two
9个回答

33

这比你想象的要容易。

首先,你需要一个将HSV或HSL转换为RGB的函数。 这里有一段C#代码来进行转换

然后,你只需在保持饱和度s和亮度l不变的情况下迭代所有可能的色调值h

如果你想要平均分布的100种彩虹颜色:

for(double i = 0; i < 1; i+=0.01)
{
    ColorRGB c = HSL2RGB(i, 0.5, 0.5);
    //do something with the color
}
你也可以通过将所有这些颜色添加到一个 List<ColorRGB> 中并返回相应的索引颜色来轻松创建所需的函数GetRainbowColor

5
请参考 http://en.wikipedia.org/wiki/HLS_color_space ,其中有一节关于将 HSL 转换为/从 RGB 的内容。 - DNNX

9
我喜欢使用这个:

我喜欢使用这个:

public static Color Rainbow(float progress)
{
    float div = (Math.Abs(progress % 1) * 6);
    int ascending = (int) ((div % 1) * 255);
    int descending = 255 - ascending;

    switch ((int) div)
    {
        case 0:
            return Color.FromArgb(255, 255, ascending, 0);
        case 1:
            return Color.FromArgb(255, descending, 255, 0);
        case 2:
            return Color.FromArgb(255, 0, 255, ascending);
        case 3:
            return Color.FromArgb(255, 0, descending, 255);
        case 4:
            return Color.FromArgb(255, ascending, 0, 255);
        default: // case 5:
            return Color.FromArgb(255, 255, 0, descending);
    }
}

简洁明了,我喜欢它。 - mafu

3

这是我喜欢使用的一个工具(输出结果为HTML RGB颜色):

public static String Rainbow(Int32 numOfSteps, Int32 step)
        {
            var r = 0.0;
            var g = 0.0;
            var b = 0.0;
            var h = (Double)step / numOfSteps;
            var i = (Int32)(h * 6);
            var f = h * 6.0 - i;
            var q = 1 - f;

            switch (i % 6)
            {
                case 0:
                    r = 1;
                    g = f;
                    b = 0;
                    break;
                case 1:
                    r = q;
                    g = 1;
                    b = 0;
                    break;
                case 2:
                    r = 0;
                    g = 1;
                    b = f;
                    break;
                case 3:
                    r = 0;
                    g = q;
                    b = 1;
                    break;
                case 4:
                    r = f;
                    g = 0;
                    b = 1;
                    break;
                case 5:
                    r = 1;
                    g = 0;
                    b = q;
                    break;
            }
            return "#" + ((Int32)(r * 255)).ToString("X2") + ((Int32)(g * 255)).ToString("X2") + ((Int32)(b * 255)).ToString("X2");
        }

那就是我一直在寻找的!谢谢。 - NPLS

1
在winforms(或任何使用GDI +的东西)中,您可以使用System.Drawing.Drawing2D.LinearGradientBrush为您执行插值。
WPF的System.Windows.Media.GradientBrush也可以工作。它是抽象的,所以您可能最终会得到WPF的LinearGradientBrush。它位于与其他不同的命名空间中。
编辑:由于问题已被编辑以指示您想要技术独立,因此我认为此答案不适用。我现在将其保留在这里,以防有人正在寻找C#中的渐变,但如果有人发现这令人反感,我将删除答案。
我快速检查了一下,看看是否可以以更独立的方式(例如获取Point数组或类似的东西)获得某些功能。看起来并非如此。

1
我看到很多代码示例都使用双精度浮点数。但是R、G、B都是字节,所以使用双精度浮点数没有意义。
顺便说一下:当你在所有可能的彩虹颜色中以0...255的范围扫过时,只有1536种可能的颜色。
每个颜色都上下扫过= 6次扫过。 使用这个算法可以得到的最大颜色数为6 * 256 = 1536种颜色。
在这里找到的任何能产生超过1536种颜色的公式都会包含重复的颜色!
以下算法仅适用于整数。
/// <summary>
/// s32_Sweeps = 4 --> Colors from blue to red, not including magenta       (1024 colors)
/// s32_Sweeps = 6 --> Complete sweep with all rainbow colors, also magenta (1536 colors)
/// </summary>
private static Color[] CalcRainbow(int s32_Sweeps)
{
    Color[] c_Colors = new Color[s32_Sweeps * 256];
    int R,G,B,P=0;
    for (int L=0; L<s32_Sweeps; L++)
    {
        for (int E=0; E<256; E++)
        {
            switch (L)
            {
                case 0: R = 0;       G = E;       B = 255;     break; // Blue...Cyan
                case 1: R = 0;       G = 255;     B = 255 - E; break; // Cyan...Green
                case 2: R = E;       G = 255;     B = 0;       break; // Green...Yellow
                case 3: R = 255;     G = 255 - E; B = 0;       break; // Yellow...Red
                case 4: R = 255;     G = 0;       B = E;       break; // Red...Magenta
                case 5: R = 255 - E; G = 0;       B = 255;     break; // Magenta...Blue
                default: throw new ArgumentException();
            }
            c_Colors[P++] = Color.FromArgb(255, R, G, B);
        }
    }
    return c_Colors;
}

0

http://colorfulconsole.com/ 这个工具可以满足你的需求,而且还可以作为NuGet包安装。 虽然它不是彩虹渐变。 但它可以在控制台中写入渐变,同时这也会让IDE感到困惑。

Colorful.Console

并且

System.Console

所以请确保定义正确的控制台。


0

0
uint32_t Wheel(byte WheelPos) { // 0 - 255 return unit32_t
  if(WheelPos < 85) {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); //red + green
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); //blue + red
  } else {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); //green + blue
  }
}

如果轮子位置是5,则返回(15, 240, 0)。
6 = (18, 237, 0)。

请添加更多细节。 - Muhammedogz
通过发布这样的垃圾内容,你在Stackoverflow上永远不会获得声誉。 - Elmue

-1

链接已失效,没有链接这个答案就毫无用处。 - Haukman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接