views:

100

answers:

4

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 typical 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
+8  A: 

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).

Oded
Yes, but not a list ordered by "standardness".
mafutrct
@mafutrct - define "standardness".
Oded
I'm thinking he means like the colours found in the widgets in the Windows colour pickers. (or "Colour Pickers" in general).
Noon Silk
@Noon Silk - yeah figured that he might be. No confirmation from the OP though :(
Oded
See updated question. Neither the colors defined in Colors not SystemColors are helping here, as they are not ordered.
mafutrct
@mafutrct - You can take the list and sort it yourself by the `A`, `R`, `G` or `B` elements as they are exposed as part of the `Color` struct.
Oded
@Oded That would be very difficult - how should I sort it? I can't think of an efficient algorithm.
mafutrct
@mafutrct `OrderBy(c=>c.R).ThenBy(c=>c.G)`? :)
bzlm
@mafutrct - See [this](http://msdn.microsoft.com/en-us/library/bb546145.aspx) - it may help. Sorting with Linq and using the `Color` struct should be easy enough (since `Color` has members for each component - i.e, `Red.R` will be 255.
Oded
@bzlm, @Oded That would be nowhere close to the list I want - colors with 40 and B0 components have to be preceded by colors with 80 components, which are preceded by 00/FF-only colors. You can extend that schema to colors with 20/60/... components and so on.
mafutrct
+1  A: 

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

Marius Schulz
+1  A: 

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 ).

zgorawski
+1  A: 

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
mafutrct