2

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
bzlm
  • 9,626
  • 6
  • 65
  • 92
mafu
  • 31,798
  • 42
  • 154
  • 247
  • What context (windows forms, WPF, web)? – Murph Sep 24 '10 at 11:17
  • Actually neither of these, but if you know of a fitting library function in e.g. WPF I'm fine with that. – mafu Sep 24 '10 at 11:19
  • So you want an array of colors sorted in some particular order? BTW: FF 00 00 is listed twice. – luiscubal Sep 24 '10 at 11:47
  • @mafutrct Sounds like your question is about sorting, not about colours? – bzlm Sep 24 '10 at 12:07
  • @bzlm Yes, the essential part is about the list of RGB values. But "sorting" that list is definitely harder than generating it. – mafu Sep 24 '10 at 12:12
  • 1
    @mafutrct I'm sure if you manually construct more of the final sequence, it will become more apparent how to generate it. (I can't see the logic behind the jump from 80 80 80 to FF (100?) 00 80 for example.) I'd experiment with nested Linq projections if I were you. :) – bzlm Sep 24 '10 at 12:22
  • @mafutrct - can you please post the exact sorting logic by which you want this ordering to occur? I don't understand the sorting logic behind your examples. – Oded Sep 24 '10 at 12:45
  • @bzlm I kind of knew how to generate it in a naive way, but it was not until a minute ago that I found an sufficiently efficient way (which I'm going to add as an answer). You are right that 80 sould read 7F, of course. I'd be interested in a Linq solution if you want to add it... :) – mafu Sep 24 '10 at 12:56
  • @Oded see said answer, it includes a list and also a test program. The ordering within a set not important though. By set I mean a tuple consisting of the same components, starting with 0/255 (8 permutations), adding 127 (19 _new_ permutations), adding 63/191, then 31/95/159/223, ... – mafu Sep 24 '10 at 13:15

4 Answers4

8

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
  • 489,969
  • 99
  • 883
  • 1,009
  • Yes, but not a list ordered by "standardness". – mafu Sep 24 '10 at 11:20
  • @mafutrct - define "standardness". – Oded Sep 24 '10 at 11:21
  • I'm thinking he means like the colours found in the widgets in the Windows colour pickers. (or "Colour Pickers" in general). – Noon Silk Sep 24 '10 at 11:24
  • @Noon Silk - yeah figured that he might be. No confirmation from the OP though :( – Oded Sep 24 '10 at 11:27
  • See updated question. Neither the colors defined in Colors not SystemColors are helping here, as they are not ordered. – mafu Sep 24 '10 at 11:32
  • @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 Sep 24 '10 at 12:00
  • @Oded That would be very difficult - how should I sort it? I can't think of an efficient algorithm. – mafu Sep 24 '10 at 12:03
  • 1
    @mafutrct `OrderBy(c=>c.R).ThenBy(c=>c.G)`? :) – bzlm Sep 24 '10 at 12:05
  • 1
    @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 Sep 24 '10 at 12:08
  • @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. – mafu Sep 24 '10 at 12:09
1

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

Marius Schulz
  • 15,976
  • 12
  • 63
  • 97
1

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
  • 2,597
  • 4
  • 30
  • 43
1

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
mafu
  • 31,798
  • 42
  • 154
  • 247