We are building a sports application and would like to incorporate team colors in various portions of the app.
Now each team can be represented using several different colors.
What I would like to do is to perform a check to verify whether the two team colors are within a certain range of each other, so that I do not display two similar colors.
So, if team 1's primary team color has a value of rgb(255,0,0) (or #FF0000), and team 2's primary color i开发者_Python百科s similar, say rgb(250,0,0), then we would choose a different color for one of the teams.
If possible, what approach could I take to perform the check?
Thanks
Here is a theoretical explanation
And the algo in C:
typedef struct {
unsigned char r, g, b;
} RGB;
double ColourDistance(RGB e1, RGB e2)
{
long rmean = ( (long)e1.r + (long)e2.r ) / 2;
long r = (long)e1.r - (long)e2.r;
long g = (long)e1.g - (long)e2.g;
long b = (long)e1.b - (long)e2.b;
return sqrt((((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8));
}
Here is pgras' algorithm in Java:
public double ColourDistance(Color c1, Color c2)
{
double rmean = ( c1.getRed() + c2.getRed() )/2;
int r = c1.getRed() - c2.getRed();
int g = c1.getGreen() - c2.getGreen();
int b = c1.getBlue() - c2.getBlue();
double weightR = 2 + rmean/256;
double weightG = 4.0;
double weightB = 2 + (255-rmean)/256;
return Math.sqrt(weightR*r*r + weightG*g*g + weightB*b*b);
}
Most answers for this question will suggest calculating the distance between two colors when mapping the RGB values into a 3D space. The problem with this technique is that two colors with similar hues, but different saturation or brightness levels may map further away from each other in 3D RGB space than two colors with different hues, but very similar saturation and brightness levels. In other words, a blue and a green may be closer in 3D RGB space than two shades of a Red. In this application, ensuring team colors differ, hue differences should weigh much more heavily than brightness and saturation.
So I would convert the color mapping from RGB to hue, saturation, and brightness levels, and then check just the hue values for sufficient distance.
Wikipedia has an explanation for converting RGB to HSV. LiteratePrograms has some sample code.
I would use 3d distance between two colors where x,y,z are R,G,B values.
Take a look at this Perl Library:
http://metacpan.org/pod/Color::Similarity::RGB
This is easy to implement yourself.
Just make sure that (R1-R2)^2 + (G1-G2)^2 + (B1-B2)^2 >= threshold^2
Wikipedia has details on a number of algorithms which can be used for this.
There is also this previous StackOverflow question: Finding an accurate “distance” between colors
From an algorithm viewpoint, this is fairly simple. Each color represents a point in a 3D space, and the difference between colors is the distance between those points.
Presumably the point here is to ensure that the colors are visibly different. If that's the case, deciding on the minimum distance is probably going to be fairly difficult. The problem is that (at least for people with normal vision) some differences are easier to see than others. For example, most people are more sensitive to small differences in shades of green than equally small changes in shades of red or blue. There are algorithms to take this into account, but they're based on average human vision, so none of them is guaranteed to be precisely correct for any one person.
Just for fun, you might want to take a look at X-rite's online color vision test.
I have used the algorithms given in the first replies although results did not meet expectations until I have found DeltaE library, which calculates the distance between colors much better.
It's for Node.js, check it here.
精彩评论