Click here to Skip to main content
Click here to Skip to main content

Random Color Generator

By , 5 Oct 2011
 
Eric,
 
Thanks for implementing my color distance code. Since you are using CIE Lab color space from Guillaume's library, I had another look at the RGB <> CIEXYZ <> CIELab formulas. They are not quite correct. In your project, you will not see a big difference. However, if you will use the lib for other purposes, you'll see a BIG difference.
 
Further, Guillaume's library uses sRGB with D50 reference white, like all other copy/paste solutions. If you would compare the conversion with PhotoShop, you'll be surprised that the results do not match. Adobe uses RGB Bradford adapted with D65 reference white.
 
If you want to use RGB Bradford adapted CIELab conversion, do the following:
 
In CIEXYZ class, add:
public static readonly CIEXYZ D50 = new CIEXYZ(0.96422, 1.00000, 0.82521);
 
In RGBtoXYZ method change matrix constants to:
0.4360747  0.3850649  0.1430804
0.2225045  0.7168786  0.0606169
0.0139322  0.0971045  0.7141733
 
In XYZtoRGB method, change matrix constants to (watchout for +/- signs):
3.1338561 -1.6168667 -0.4906146
-0.9787684  1.9161415  0.0334540
 0.0719453 -0.2289914  1.4052427
 
In XYZtoLab method:
change D65 to D50
 
In LabtoXYZ method:
change D65 to D50
 
Here are the corrections for sRGB with D65 reference white:
 
public static CIEXYZ RGBtoXYZ(int red, int green, int blue)
{		
	// normalize red, green, blue values
	double rLinear = (double)red/255.0;
	double gLinear = (double)green/255.0;
	double bLinear = (double)blue/255.0;
 
	// convert to a sRGB form
	// corrected 2.2 to 2.4 (Rob)
	double r = (rLinear > 0.04045)? Math.Pow((rLinear + 0.055)/(1 + 0.055), 2.4) : (rLinear/12.92) ;
	double g = (gLinear > 0.04045)? Math.Pow((gLinear + 0.055)/(1 + 0.055), 2.4) : (gLinear/12.92) ;
	double b = (bLinear > 0.04045)? Math.Pow((bLinear + 0.055)/(1 + 0.055), 2.4) : (bLinear/12.92) ;
 
	// converts using sRGB Working Space Matrix and D65 Reference White
	// expanded constants (Rob)
	return new CIEXYZ(
		(r*0.4124564 + g*0.3575761 + b*0.1804375),
		(r*0.2126729 + g*0.7151522 + b*0.0721750),
		(r*0.0193339 + g*0.1191920 + b*0.9503041)
		);
}
 
public static RGB XYZtoRGB(double x, double y, double z)
{
	// using sRGB Working Space Matrix and D65 Reference White
	// expanded constants (Rob)
	double[] Clinear = new double[3];
	Clinear[0] = x*3.2404542 - y*1.5371385 - z*0.4985314; // red
	Clinear[1] = -x*0.9692660 + y*1.8760108 - z*0.0415560; // green
	Clinear[2] = x*0.0556434 - y*0.2040259 + z*1.0572252; // blue

	for(int i=0; i<3; i++)
	{
		Clinear[i] = (Clinear[i]<=0.0031308)? 12.92*Clinear[i] : (1+0.055)* Math.Pow(Clinear[i], (1.0/2.4)) - 0.055;
	}
 
	return new RGB(
		Convert.ToInt32( Double.Parse(String.Format("{0:0.00}", Clinear[0]*255.0)) ), 
		Convert.ToInt32( Double.Parse(String.Format("{0:0.00}", Clinear[1]*255.0)) ), 
		Convert.ToInt32( Double.Parse(String.Format("{0:0.00}", Clinear[2]*255.0)) )
		);
}
 
Happy coding.
 
Rob

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Rob2412
Switzerland Switzerland
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralReason for my vote of 5 Rob seems to really know the subject...memberEric Ouellet4 Oct '11 - 9:34 
GeneralHello Rob, This is what I did and would appreciate your co...memberEric Ouellet4 Oct '11 - 9:03 
GeneralThanks Rob, To be honnest, your alternative almost gave me ...memberEric Ouellet4 Oct '11 - 8:19 
Thanks Rob,
 
To be honnest, your alternative almost gave me an heart attack...
I know the world of mathematics and color like a chicken know how to fly.
 
But I took a look and try to understand.
 
There is one thing that I fail to understand. You wrote "Adobe uses RGB Bradford adapted with D65 reference white." and "If you want to use RGB Bradford adapted CIELab conversion do the following:" and ask to change from D65 to D50 at 2 places. I'm a bit confused. You want to turn that from D65 to D50 reference white or the opposite ?
 
Thanks,
Eric
 
Note: Writing a tips and tricks is a real adventure but I like it Smile | :)

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 5 Oct 2011
Article Copyright 2011 by Rob2412
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid