3

Given either HSV or RGB, is there an algorithm that can prodice random colors for a background that are guaranteed to be readable on a pure white font?

It does not have to be a language specific implementation, though I am using C#.

Thanks

I made this, but I am sure it could be improved:

   public static System.Drawing.Color GenerateRandomLiteColor()
        {
            var rnd = new Random(DateTime.Now.Millisecond);
            double mul = 240.0;
            HSLColor c = new HSLColor(rnd.NextDouble() * mul,
                ((rnd.NextDouble() * 0.6) + 0.5) * mul, ((rnd.NextDouble() * 0.35) + 0.5) * mul);

            string s = c.ToRGBString();
            return c;
        }
user2043533
  • 731
  • 3
  • 9
  • 23
  • 1
    black, black, black, black, ...; is that random enough? – John Dvorak Mar 08 '13 at 16:49
  • I was hoping there would not be any silly response like this. Obviously it is a bit subjective... but within reason... – user2043533 Mar 08 '13 at 16:50
  • Guaranteed? That's a bit subjective. One person's readable is another's unreadable. Also, you need to be more specific. I can choose 2 different dark color values and randomly pick from those 2 and satisfy your current question. – hatchet - done with SOverflow Mar 08 '13 at 16:52
  • That was what I'm trying to demonstrate. – John Dvorak Mar 08 '13 at 16:52
  • I used to have a script that attempted to do this. It would take the foreground and background, and convert the RGB to grayscale ((0.2989 * R + 0.5870 * G + 0.1140 * B)*255), and see if the grayscale difference was higher than a certain threshold. This worked ok, but resulted in some combinations that were too high contrast. I ended up just storing the combinations I liked and selecting from that, instead. – Scott Mermelstein Mar 08 '13 at 16:53
  • 1
    Clarification: should we try to generate a sequence of distinct colors, or the samples may be independent? – John Dvorak Mar 08 '13 at 16:53
  • What about something like this: http://stackoverflow.com/a/43235/21727 – mbeckish Mar 08 '13 at 17:01
  • 2
    @JanDvorak, you're obviously a fan of this random number generator: http://dilbert.com/strips/comic/2001-10-25/ – Mark Ransom Mar 08 '13 at 17:30
  • My guess is that you also want your background colors to be distinguishable from *each other*. If so, you might want to look at this [related question](http://stackoverflow.com/questions/8189522/how-can-i-generate-a-generally-aesthetically-pleasing-range-of-line-graph-colors/8190463#8190463) – comingstorm Mar 08 '13 at 17:53
  • Color perception is surprisingly complex. I doubt you need anything this advanced but FYI have a look at [this Question](http://stackoverflow.com/q/5774152/156755) – Basic Mar 08 '13 at 21:11

2 Answers2

2

Using HSL you could say anything with L below a certain value is visible, it has sufficient darkness for enough contrast. But this would be a subjective value. You could make H and S random. HSL can be then converted to HSV or RGB.

L should not be random. Or it could be but within a range that you have predefined to give sufficient contrast. ie below a fixed Lmax.

QuentinUK
  • 2,997
  • 21
  • 20
2

For RGB there is a formula which calculates brightness of color:

0.299 * R + 0.587 * G + 0.114 * B

As you see each of R,G,B colors has its own brightness coefficient. To generate readable font on white background, generate completely random color. Then check if its brightness is less than some predefined constant C. If it exceeds C and equals to some D > C, then multiply each of R, G, B values by C / D to make the brightness equal to C.

artahian
  • 2,093
  • 14
  • 17
  • 1
    Instead of multiplying by `C/D`, multiply by a random number from 0 to `C/D`. Otherwise your distribution will tend to favor the lighter colors. – Mark Ransom Mar 08 '13 at 18:52
  • I thought about a better approach, we should denote by **D** the brightness of white color, and thus we get **D = 255** by the formula above. Then each color should be multiplied by **C / D** without checking any condition. – artahian Mar 09 '13 at 08:21