Click here to Skip to main content
15,886,095 members
Articles / Programming Languages / C#
Alternative
Tip/Trick

Random Color Generator

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
5 Oct 2011CPOL 10.1K   1   3
Eric,Thank...
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:
C#
public static readonly CIEXYZ D50 = new CIEXYZ(0.96422, 1.00000, 0.82521);


In RGBtoXYZ method change matrix constants to:
C#
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):
C#
3.1338561 -1.6168667 -0.4906146
-0.9787684  1.9161415  0.0334540
 0.0719453 -0.2289914  1.4052427


In XYZtoLab method:
C#
change D65 to D50


In LabtoXYZ method:
C#
change D65 to D50


Here are the corrections for sRGB with D65 reference white:

C#
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)


Written By
Switzerland Switzerland
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralReason for my vote of 5 Rob seems to really know the subject... Pin
Eric Ouellet4-Oct-11 9:34
professionalEric Ouellet4-Oct-11 9:34 
GeneralHello Rob, This is what I did and would appreciate your co... Pin
Eric Ouellet4-Oct-11 9:03
professionalEric Ouellet4-Oct-11 9:03 
GeneralThanks Rob, To be honnest, your alternative almost gave me ... Pin
Eric Ouellet4-Oct-11 8:19
professionalEric Ouellet4-Oct-11 8:19 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.