It just so happens I needed this function for a project not long ago.
private int PerceivedBrightness(Color c)
{
return (int)Math.Sqrt(
c.R * c.R * .241 +
c.G * c.G * .691 +
c.B * c.B * .068);
}
This formula I found on the web at Nbd Tech that dealt with perceived colors and color conversion formula. The site gives a lot of information that is helpful.
Here’s how to use this to select black or white:
var foreColor = (PerceivedBrightness(backColor) > 130 ? Color.Black : Color.White);
You can use a value other than 130 as the cutoff; it is preference.
Update: According to Darel Rex Finley at his site:
The values I came up with by playing with Photoshop were actually .241, .691, and .068, but I have since been informed that the values .299, .587, and .114 are more accurate.
This specification follows ITU-R Recommendation BT.601 (or Rec. 601 for short). The site I mentioned above, Nbd Tech, hasn’t yet been updated to reflect this.
Based on this, here is the updated method (thanks to DTI-Matt for the comment):
private int PerceivedBrightness(Color c)
{
return (int)Math.Sqrt(
c.R * c.R * .299 +
c.G * c.G * .587 +
c.B * c.B * .114);
}
Note on threshold preference:
Colors with a perceived brightness near the middle (e.g. 120-140) will be more subjective. For example, it’s debatable whether red (FF0000), which evaluates to 139, is clearer with a black or white overlay.