开发者

How do I generate this specific sequence of numbers?

Apparently there is no predefined list available in .net.

I'd like to use a number of standard colors, e.g. something like red, green, blue, yellow, ... i.e. the t开发者_运维问答ypical colors consisting of 00 and FF components, followed by those with additional 7F components, ...

Is there a way to retrieve these "standard" colors or do I have to write the IEnumerable<Color> myself?

Edit: This is a possible output for the RGB values.

Please note that order of sets matters in that the 00/FF enumeration has to be complete before 80 is added, and the 00/80/FF enumeration has to be complete before adding 40/B0, and so on. The order within a set does not matter (i.e. 00 FF 00 may come before 00 00 FF).

00 00 00 // start out with 00 and FF components
00 00 FF
00 FF 00
FF 00 00
FF FF 00
FF 00 FF
00 FF FF
FF FF FF
00 00 80 // ok, now add 80
00 80 00
...
80 80 80
FF 00 80
FF 80 00
FF 80 80
80 FF 00
80 FF 80
FF FF 80
...
// now add 40 and B0


The Colors class has a number of pre-defined ARGB colors on it, as does the Color struct. These hold things like Yellow, White, Green etc...

If you want the user defined system colors, you can use the SystemColors class which has things like ActiveBorder, WindowText etc...


Update:

There is nothing in the framework that sorts colors by their ARGB values as such, since it doesn't really make much sense

You can use Linq to sort a list of colors by their components (OrderBy extension method).


Probably, the SystemColors class is the right thing for you.


AFAIK "Standard" colors are not equal to colors with RGB value based on patter that you described. For example purple color has #B803FF RGB value ( where similar 'fuchsia' has #FF00FF ).


This is a reasonably fast way to generate the sequence:

public static IEnumerable<Color> StandardColors ()
{
    int r = 0;
    int g = 0;
    int b = 0;
    int inc = 0x100;

    yield return Color.FromArgb (0, 0, 0);

    while (true) {
        if (((r | g | b) & inc) != 0) {
            int outR = r == 0 ? 0 : r - 1;
            int outG = g == 0 ? 0 : g - 1;
            int outB = b == 0 ? 0 : b - 1;
            yield return Color.FromArgb (outR, outG, outB);
        }

        r += inc;
        if (r > 256) {
            r = 0;
            g += inc;

            if (g > 256) {
                g = 0;
                b += inc;

                if (b > 256) {
                    b = 0;
                    inc >>= 1;

                    if (inc <= 1) {
                        break;
                    }
                }
            }
        }
    }
}

This can certainly be improved. For instance, having a separate outR/G/B variable should be avoided, and incrementing should be via 2*inc starting from an odd (based on inc) value to avoid having to test if the value was already generated earlier.

Using this test

static void Main (string[] args)
{
    var colors = StandardColorEnumerator.StandardColors ().Take (15)
        .Concat (StandardColorEnumerator.StandardColors ().Skip (1000).Take (10));
    foreach (var color in colors) {
        Console.WriteLine (color.B + "\t" + color.G + "\t" + color.R);
    }

    Console.ReadKey (true);
}

the following output is generated:

0       0       0
0       0       255
0       255     0
0       255     255
255     0       0
255     0       255
255     255     0
255     255     255
0       0       127
0       127     0
0       127     127
0       127     255
0       255     127
127     0       0
127     0       127

15      47      191
15      47      207
15      47      223
15      47      239
15      47      255
15      63      0
15      63      15
15      63      31
15      63      47
15      63      63
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜