Calculating color differences

Share your advanced PureBasic knowledge/code with the community.
eesau
Enthusiast
Enthusiast
Posts: 589
Joined: Fri Apr 27, 2007 12:38 pm
Location: Finland

Calculating color differences

Post by eesau »

Here's some code to calculate the difference between two RGB colors (measured from 0 to 100). Very useful in image and color manipulation. It's based on Emanuele Feronatos php code in his blog entry (found here).

Code: Select all

Structure ColorRGB
	R . a
	G . a
	B . a
EndStructure

Structure ColorXYZ
	X . f
	Y . f
	Z . f
EndStructure

Structure ColorLAB
	L . f
	A . f
	B . f
EndStructure

Structure ColorModels
	StructureUnion
		ColorRGB . ColorRGB
		ColorXYZ . ColorXYZ
		ColorLAB . ColorLAB
	EndStructureUnion
EndStructure

Procedure RGBtoXYZ ( *Color . ColorModels )
	
	Protected R . f = *Color \ ColorRGB \ R / 255
	Protected G . f = *Color \ ColorRGB \ G / 255
	Protected B . f = *Color \ ColorRGB \ B / 255
					
	If R > 0.04045 : R = ( R + 0.055 ) / 1.055 : R = Pow ( R , 2.4 ) : Else : R = R / 12.92 : EndIf
	If G > 0.04045 : G = ( G + 0.055 ) / 1.055 : G = Pow ( G , 2.4 ) : Else : G = G / 12.92 : EndIf
	If B > 0.04045 : B = ( B + 0.055 ) / 1.055 : B = Pow ( B , 2.4 ) : Else : B = B / 12.92 : EndIf
	
	R * 100 : G * 100 : B * 100

	*Color \ ColorXYZ \ X = R * 0.4124 + G * 0.3576 + B * 0.1805
	*Color \ ColorXYZ \ Y = R * 0.2126 + G * 0.7152 + B * 0.0722
	*Color \ ColorXYZ \ Z = R * 0.0193 + G * 0.1192 + B * 0.9505
		
	ProcedureReturn #True
	
EndProcedure

Procedure XYZtoLAB ( *Color . ColorModels )

	Protected X . f = *Color \ ColorXYZ \ X / 95.047
	Protected Y . f = *Color \ ColorXYZ \ Y / 100 
	Protected Z . f = *Color \ ColorXYZ \ Z / 108.883
	
	If X > 0.008856 : X = Pow ( X , 1/3 ) : Else : X = ( 7.787 * X ) + ( 16/116 ) : EndIf
	If Y > 0.008856 : Y = Pow ( Y , 1/3 ) : Else : Y = ( 7.787 * Y ) + ( 16/116 ) : EndIf
	If Z > 0.008856 : Z = Pow ( Z , 1/3 ) : Else : Z = ( 7.787 * Z ) + ( 16/116 ) : EndIf
	
	*Color \ ColorLAB \ L = ( 116 * Y ) - 16
	*Color \ ColorLAB \ A = 500 * ( X - Y )
	*Color \ ColorLAB \ B = 200 * ( Y - Z )

	ProcedureReturn #True

EndProcedure

Procedure . f ColorDifference ( Color1 , Color2 )

	Protected Alpha . ColorModels
	Protected Omega . ColorModels
	
	Alpha \ ColorRGB \ R = Red ( Color1 )
	Alpha \ ColorRGB \ G = Green ( Color1 )
	Alpha \ ColorRGB \ B = Blue ( Color1 )

	Omega \ ColorRGB \ R = Red ( Color2 )
	Omega \ ColorRGB \ G = Green ( Color2 )
	Omega \ ColorRGB \ B = Blue ( Color2 )

	RGBtoXYZ ( @Alpha ) : XYZtoLAB ( @Alpha )
	RGBtoXYZ ( @Omega ) : XYZtoLAB ( @Omega )

	Protected C1 . f = Sqr ( Alpha \ ColorLAB \ A * Alpha \ ColorLAB \ A + Alpha \ ColorLAB \ B * Alpha \ ColorLAB \ B )
	Protected C2 . f = Sqr ( Omega \ ColorLAB \ A * Omega \ ColorLAB \ A + Omega \ ColorLAB \ B * Omega \ ColorLAB \ B )

	Protected DC . f = C1 - C2
	
	Protected DL . f = Alpha \ ColorLAB \ L - Omega \ ColorLAB \ L
	Protected DA . f = Alpha \ ColorLAB \ A - Omega \ ColorLAB \ A
	Protected DB . f = Alpha \ ColorLAB \ B - Omega \ ColorLAB \ B
	
	Protected DH . f = Sqr ( DA*DA + DB*DB + DC*DC )
	
	Protected D1 . f = DL
	Protected D2 . f = DC / ( 1 + 0.045 * C1 )
	Protected D3 . f = DH / ( 1 + 0.015 * C1 )
	
	ProcedureReturn Sqr ( D1*D1 + D2*D2 + D3*D3 )

EndProcedure

Debug ColorDifference ( #White , #White )
Debug ColorDifference ( #White , #Black )
Debug ColorDifference ( #Gray , #Black )
Debug ColorDifference ( #Red , #Black )
Debug ColorDifference ( #Red , #White )
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Calculating color differences

Post by luis »

Wow, that's very interesting... I was just looking for something like that, thank you.
"Have you tried turning it off and on again ?"
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: Calculating color differences

Post by rsts »

Very nice.

This would have helped me when I was looking for complementary colors sometime back, because I really needed something like this.

cheers
Post Reply