Code archives/Graphics/Color Class

This code has been declared by its author to be Public Domain code.

Download source code

Color Class by N2009
Internally, this is just RGBA, so if that's a problem, you might want to rewrite this as a class cluster instead. That being said, this essentially just provides a small-ish, immutable class to work with colors in a few different formats.

Might be useful for something, I'm not sure, but it's some old code of mine that I modified a bit after finding it since I wasn't happy with some stuff in it.
SuperStrict

Import Brl.Math

Private

' 1 over 255
Const b2f! = 0.003921568627450980392156862745098!

'#region Utility - Value clamping
Function ClampD!( a!, b!, c! )
	Return Min( Max( a, b ), c )
End Function
'#endregion

Public

Type TColor

	Field r!=0!, g!=0!, b!=0!, a!=0!

	'#region RGBA

	Function ForRGBA:TColor( r!, g!, b!, a! )
		Return New TColor.InitWithRGBA( r, g, b, a )
	End Function
	
	Method InitWithIntComponents:TColor( r%, g%, b%, a% )
		Self.r = r*b2f
		Self.g = g*b2f
		Self.b = b*b2f
		Self.a = a*b2f
		Return Self
	End Method
	
	Method InitWithRGBA:TColor( r!, g!, b!, a! )
		Self.r = r
		Self.g = g
		Self.b = b
		Self.a = a
		Return Self
	End Method

	Method GetRGBA( r! Var, g! Var, b! Var, a! Var )
		r = Self.r
		g = Self.g
		b = Self.b
		a = Self.a
	End Method
	
	Method GetRed!()
		Return r
	End Method
	
	Method GetGreen!()
		Return g
	End Method
	
	Method GetBlue!()
		Return b
	End Method
	
	Method GetAlpha!()
		Return a
	End Method

	Method ToInt%( )
		Local ir%, ig%, ib%, ia%
		ir = Min( Max( r*255, 0 ), 255 )
		ig = Min( Max( g*255, 0 ), 255 )
		ib = Min( Max( b*255, 0 ), 255 )
		ia = Min( Max( a*255, 0 ), 255 )
		Return ia Shl 24 | ir Shl 16 | ig Shl 8 | ib
	End Method
	
	Method IntComponents(r% Var, g% Var, b% Var, a% Var)
		r = Self.r * 255
		g = Self.g * 255
		b = Self.b * 255
		a = Self.a * 255
	End Method

	Function ForInt:TColor( rgba:Int )
		Return New TColor.InitWithRGBA( ..
			(rgba & 255)*b2f, ..
			(rgba Shr 8 & 255)*b2f, ..
			(rgba Shr 16 & 255)*b2f, ..
			(rgba Shr 24)*b2f )
	End Function
	
	'#endregion

	'#region HSV

	Method InitWithHSV:TColor( h!, s!, v!, a!=1! )
		Local hi%, f!, p!, q!, t!
		f = h / 60!
		hi = Int(f) Mod 6
		f :- hi
		p = V*(1!-s)
		q = V*(1!-(f*s))
		t = V*(1!-((1!-f)*s))
		Select hi
			Case 0; r=V;	g=t;	b=p
			Case 1; r=q;	g=V;	b=p
			Case 2; r=p;	g=V;	b=t
			Case 3; r=p;	g=q;	b=V
			Case 4; r=t;	g=p;	b=V
			Case 5; r=V;	g=p;	b=q
		End Select
		Self.a = a
		Return Self
	End Method

	Function ForHSV:TColor( h!, s!, v!, a!=1! )
		Return New TColor.InitWithHSV( h, s, v, a )
	End Function

	Method ToHSV( h! Var, s! Var, v! Var )
		Local mn!, mx!, dif!, ad!, dv!, md!
		If ( r < g and r < b )
			mn = r
		Else If ( g < b )
			mn = g
		Else
			mn = b
		EndIf

		If ( r > g and r > b )
			mx = r
			dif = g-b
			ad = 0!
		Else If ( g > b )
			dif = b-r
			mx = g
			ad = 120!
		Else
			dif = r-g
			ad = 240!
			mx = b
		EndIf
		
		md = mx-mn

		h = (60!*(dif / md))+ad
		s = md/mx
		V = mx
	End Method
	
	Method GetHue!()
		Local h!,s!,v!
		ToHSV(h,s,v)
		Return h
	End Method
	
	Method GetSaturation!()
		Local h!,s!,v!
		ToHSV(h,s,v)
		Return s
	End Method
	
	Method GetValue!()
		Local h!,s!,v!
		ToHSV(h,s,v)
		Return v
	End Method
	
	'#endregion
	
	'#region CMYK
	
	Method InitWithCMYK:TColor( c!, m!, y!, k!, a!=1! )
		Return Self.InitWithRGBA( ..
			1! - (c*(1!-k)+k), ..
			1! - (m*(1!-k)+k), ..
			1! - (y*(1!-k)+k), a )
	End Method
	
	Function ForCMYK:TColor( c!, m!, y!, k!, a!=1! )
		Return New TColor.InitWithCMYK( c, m, y, k, a )
	End Function

	Method ToCMYK( c! Var, m! Var, y! Var, k! Var )
		Local cmy![] = [1!-r, 1!-g, 1!-b]
		Local sm% = 0
		
		If cmy[1] < cmy[0] And cmy[1] < cmy[2] Then
			sm = 1
		ElseIf cmy[2] < cmy[0] And cmy[2] < cmy[1] Then
			sm = 2
		EndIf
		
		If cmy[sm] >= 1 Then
			c = 0!
			m = 0!
			y = 0!
			k = 1!
		Else
			k = cmy[sm]
			Local kd! = 1.0 / (1! - k)
			c = (cmy[0]-k)*kd
			m = (cmy[1]-k)*kd
			y = (cmy[2]-k)*kd
		EndIf
	End Method
	
	Method GetCyan!()
		Local c!,m!,y!,k!
		ToCMYK(c,m,y,k)
		Return c
	End Method
	
	Method GetMagenta!()
		Local c!,m!,y!,k!
		ToCMYK(c,m,y,k)
		Return m
	End Method
	
	Method GetYellow!()
		Local c!,m!,y!,k!
		ToCMYK(c,m,y,k)
		Return y
	End Method
	
	Method GetKey!()
		Local c!,m!,y!,k!
		ToCMYK(c,m,y,k)
		Return k
	End Method
	
	'#endregion

	'#region Operations

	Method Multiply:TColor( m:TColor )
		Return New TColor.InitWithRGBA( r*m.r, g*m.g, b*m.b, a*m.a )
	End Method

	Method Add:TColor( o:TColor )
		Return New TColor.InitWithRGBA( r+o.r, g+o.g, b+o.b, a+o.a )
	End Method

	Method Subtract:TColor( o:TColor )
		Return New TColor.InitWithRGBA( r-o.r, g-o.g, b-o.b, a-o.a )
	End Method
	
	Method Clamp:TColor( bot!, top! )
		Return New TColor.InitWithRGBA(..
			ClampD( r, bot, top ),..
			ClampD( g, bot, top ),..
			ClampD( b, bot, top ),..
			ClampD( a, bot, top ) )
	End Method
	
	Method Scale:TColor( x! )
		Return New TColor.InitWithRGBA(r*x, g*x, b*x, a*x)
	End Method
	
	Method Invert:TColor()
		Return New TColor.InitWithRGBA(1!-r, 1!-g, 1!-b, 1!-a)
	End Method
	
	' If no function is specified, default to linear interpolation
	Method Interpolate:TColor( other:TColor, delta:Double, fn:Double(start:Double, finish:Double, delta:Double, context:Object)=Null, context:Object=Null )
		delta = ClampD(delta, 0!, 1!)
		If fn Then
			Return New TColor.InitWithRGBA( ..
				fn(r, other.r, delta, context), ..
				fn(g, other.g, delta, context), ..
				fn(b, other.b, delta, context), ..
				fn(a, other.a, delta, context) )
		EndIf
		Local invdelta:Double = (1.0! - delta)
		Return New TColor.InitWithRGBA( ..
			other.r*delta + r*invdelta, ..
			other.g*delta + g*invdelta, ..
			other.b*delta + b*invdelta, ..
			other.a*delta + a*invdelta)
	End Method
	
	'#endregion

	'#region Colors

	Function White:TColor( ); Return New TColor.InitWithRGBA( 1!, 1!, 1!, 1! ); End Function
	Function Red:TColor( ); Return New TColor.InitWithRGBA( 1!, 0!, 0!, 1! ); End Function
	Function Green:TColor( ); Return New TColor.InitWithRGBA( 0!, .75!, 0!, 1! ); End Function
	Function Blue:TColor( ); Return New TColor.InitWithRGBA( 0!, 0!, .75!, 1! ); End Function
	Function Lime:TColor( ); Return New TColor.InitWithRGBA( .25!, 1!, 0!, 1! ); End Function
	Function LightGreen:TColor( ); Return New TColor.InitWithRGBA( .4!, 1!, .4!, 1! ); End Function
	Function Pink:TColor( ); Return New TColor.InitWithRGBA( 1!, .25!, .25!, 1! ); End Function
	Function Purple:TColor( ); Return New TColor.InitWithRGBA( 1!, 0!, .5!, 1! ); End Function
	Function Turqoise:TColor( ); Return New TColor.InitWithRGBA( 0!, 1!, 1!, 1! ); End Function
	Function Grey:TColor( ); Return New TColor.InitWithRGBA( .5!, .5!, .5!, 1! ); End Function
	Function Black:TColor( ); Return New TColor.InitWithRGBA( 0!, 0!, 0!, 1! ); End Function
	Function Yellow:TColor( ); Return New TColor.InitWithRGBA( 1!, 1!, 0!, 1! ); End Function
	Function LightBlue:TColor( ); Return New TColor.InitWithRGBA( .4!, .4!, 1!, 1! ); End Function
	Function Maroon:TColor( ); Return New TColor.InitWithRGBA( .5!, 0!, 0!, 1! ); End Function
	Function Orange:TColor( ); Return New TColor.InitWithRGBA( 1!, .55!, 0!, 1! ); End Function
	Function Brown:TColor( ); Return New TColor.InitWithRGBA( .5!, .4!, 0!, 1! ); End Function
	Function Clear:TColor( ); Return New TColor.InitWithRGBA( 1!, 1!, 1!, 0! ); End Function

	'#endregion
	
	Method ToString$()
		Return "#<TColor:0x"+Super.ToString()+" @r="+r+" @g="+g+" @b="+b+" @a="+a+">"
	End Method
End Type

Comments

Jesse2009
show off. :)
I like it. I was going to include hsv in the one I made when I needed it. Now I am going to incorporate this one(yours) to my ARGB and take the credit for it. ;)
here hsv to rgb and vice versa in case you or soemeone here find it usefull:

Function HSVtoRGB(h:Float, s:Float, v:Float, r:Float Var, g:Float Var, b:Float Var) 
 
    Local i:Int 
    Local f:Float, p:Float, q:Float, t:Float,hTemp:Float 
  
    If s = 0.0 Or h = -1.0   ' s==0? Totally unsaturated = grey so R,G And B all equal value 
      b= v
	 g= v
	 r= v 
      Return 
    EndIf
 
    hTemp = h/60.0 
    i = Floor(hTemp)                ' which sector 
    f = hTemp - i                   ' how far through sector 
    p = v * ( 1 - s ) 
    q = v * ( 1 - s * f ) 
    t = v * ( 1 - s * ( 1 - f ) ) 
  
    Select i  
    	Case 0
		r = v
		g = t
		b = p 
    	Case 1
		r = q
		g = v
		b = p 
    	Case 2
		r = p
		g = v
		b = t 
    	Case 3
		r = p
		g = q
		b = v
    	Case 4
		r = t
		g = p
		b = v 
    	Case 5
		r = v
		g = p
		b = q 
    End Select 
End Function 
  

'*************************************************************************
Function RGBtoHSV(r:Float, g:Float, b:Float, h:Float Var, s:Float Var, v:Float Var) 
 
     Local mn:Float = r
	Local mx:Float = r
     Int maxVal=0
  
     If g > mx
		mx=g
		maxVal=1
	EndIf 
     If b > mx
		mx=b
		maxVal=2
	EndIf
     If g < mn mn=g 
     If b < mn mn=b  
    delta:Float = mx - mn 
  
    v = mx  
    If mx <> 0 
      s = delta / mx  
    Else  
      s = 0 
      h = 0 
      Return 
    EndIf 
    If s=0.0 
      h=-1 
      Return 
    Else 
      
      Select maxVal 
      	Case 0 
			h = ( g - b ) / delta         ' yel < h < mag 
      	Case 1 
			h = 2 + ( b - r ) / delta     ' cyan < h < yel 
      	Case 2 
			h = 4 + ( r - g ) / delta     ' mag < h < cyan 
      End Select 
    End If 
  
    h :* 60 
    If h < 0 Then h :+ 360 
End Function



N2009
Added an interpolate method. Takes a function to customize the interpolation, and a context object for that function if needed, otherwise defaults to linear interpolation.


Code Archives Forum