[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference noted::hackers_v1

Title:-={ H A C K E R S }=-
Notice:Write locked - see NOTED::HACKERS
Moderator:DIEHRD::MORRIS
Created:Thu Feb 20 1986
Last Modified:Mon Aug 03 1992
Last Successful Update:Fri Jun 06 1997
Number of topics:680
Total number of notes:5456

600.0. "HLS & RGB" by USHS01::BLANDO (Reality, what a concept!) Tue Nov 17 1987 17:58

    Does anyone know/have the equation to relate HLS to RGB values?
    
    FJBlando
T.RTitleUserPersonal
Name
DateLines
600.1CSSAUS::HUNTERMonkey with a diagnostic trackWed Nov 18 1987 03:31302
    I can give you a pascal program that goes the other way,  from RGB
    to HLS. It has a function inside that goes the way you want to go.
    Sorry about the lack of comments but this was a quick hack.
    
    Warwick.

Program RGB_to_HLS_Table(Input,Output);

Var 
	RedCount,GreenCount,BlueCount,Red,Green,Blue : Real;
	Hue,Lightness,Saturation : Real;


Function Maximum(Red,Green,Blue : Real):Real;

Var
	Temp : Real;
                                           
Begin

	Temp := Red;
	If Blue > Temp Then
		Temp := Blue;
	If Green > Temp Then 
		Temp := Green;
                    
	Maximum := Temp;

End {Maximum};

Function Minimum(Red,Green,Blue : Real):Real;

Var
	Temp : Real;
                                           
Begin

	Temp := Red;
	If Blue < Temp Then
		Temp := Blue;
	If Green < Temp Then 
		Temp := Green;
                    
	Minimum := Temp;

End {Minimum};

Procedure RGB_to_HLS(Red,Green,Blue: Real; Var Hue,Lightness,Saturation: Real);

Var
	Max,Min,Redc,Greenc,Bluec : Real;

Begin

	Max := Maximum(Red,Green,Blue);
	Min := Minimum(Red,Green,Blue);
	Lightness := (Max + Min)/2;	{Lightness}

	{ Calculate Saturation }
	If Max = Min Then {Achromatic Case}
	    Begin 
		Saturation := 0;
		Hue := 0;
	    End 
	Else 
	    Begin 		{Chromatic Case}
		if Lightness <= 0.5 Then
			Saturation := (Max - Min)/(Max + Min)
		Else
			Saturation := (Max - Min)/(2 - Max - Min);
		{Calculate Hue}
		Redc := (Max - Red)/(Max - Min);
		Greenc := (Max - Green)/(Max - Min);
		Bluec := (Max - Blue)/(Max - Min);
	        If Red = Max Then
			Hue := Bluec - Greenc
		Else If Green = Max Then
			Hue := 2 + Redc - Bluec
		Else If Blue = Max Then
			Hue := 4 + Greenc - Redc;
		Hue := Hue * 60;
		If Hue < 0.0 Then 
			Hue := Hue + 360;
	    End; {Chromatic Case}

End {RGB_to_HLS};

Procedure HLS_to_RGB( Var Red,Green,Blue:Real; Hue,Lightness,Saturation:Real);

Var
	M1,M2: Real;

Function Value(N1,N2,Hue:Real):Real;

    Begin
	If Hue > 360 Then
		Hue := Hue - 360;
	If Hue < 0 Then
		Hue := Hue + 360;
	If Hue < 60 Then
		Value := N1 + (N2 - N1)*Hue/60
	Else If Hue < 180 Then
		Value := N2
	Else If Hue < 240 Then
		Value := N1 + (N2 - N1)*(240 - Hue)/60
	Else
		Value := N1;
    End { Value};

Begin

	If Lightness < 0.5 Then
		M2 := Lightness * (1 + Saturation)
	Else
		M2 := Lightness + Saturation - Lightness * Saturation;

	M1 := 2 * Lightness - M2;

	If Saturation = 0 Then
		If Hue = 0 Then 
		    Begin
			Red := 1;
			Green := 1;
			Blue := 1
		    End 
		Else
			Writeln('Error Saturation = 0 and Hue <> 0')
	Else
	    Begin
		Red := Value(M1,M2,Hue + 120);
		Green := Value(M1,M2,Hue);
		Blue := Value(M1,M2,Hue - 120); 
	    End;

End {HLS_to_RGB};

Begin

	Writeln(' ');

	RedCount := 0;
	BlueCount := 0;
	GreenCount := 0;

	While RedCount <= 1.0 Do Begin
	    GreenCount := 0;
	    While GreenCount <= 1.00 Do Begin
		BlueCount := 0;
		While BlueCount <= 1.00 Do Begin
		    RGB_to_HLS(RedCount,
		    	       GreenCount,
			       BlueCount,
			       Hue,
	    		       Lightness,
			       Saturation);
		    Write(RedCount:8:2,
			GreenCount:8:2,
			BlueCount:8:2,
			Hue:8:2,
		    	Lightness:8:2,
	       	    	Saturation:8:2);
		    HLS_to_RGB(Red,
		    	       Green,
			       Blue,
			       Hue,
	    		       Lightness,
			       Saturation);
		    Writeln(Red:8:2,
			Green:8:2,
			Blue:8:2);
		    Writeln((Red - RedCount):8:2,
			    (Green - GreenCount):8:2,
			    (Blue - BlueCount):8:2);
		    BlueCount := BlueCount + 0.3333;
                End {While Blue};
		GreenCount := GreenCount + 0.3333;
	    End {While Green};
	    RedCount := RedCount + 0.3333;
	End {While Red};

End.
Program RGB_to_HLS_Table(Input,Output);

Var 
	RedCount,GreenCount,BlueCount : Real;
	Hue,Lightness,Saturation : Real;


Function Maximum(Red,Green,Blue : Real):Real;

Var
	Temp : Real;
                                           
Begin

	Temp := Red;
	If Blue > Temp Then
		Temp := Blue;
	If Green > Temp Then 
		Temp := Green;
                    
	Maximum := Temp;

End {Maximum};

Function Minimum(Red,Green,Blue : Real):Real;

Var
	Temp : Real;
                                           
Begin

	Temp := Red;
	If Blue < Temp Then
		Temp := Blue;
	If Green < Temp Then 
		Temp := Green;
                    
	Minimum := Temp;

End {Minimum};

Procedure RGB_to_HLS(Red,Green,Blue: Real; Var Hue,Lightness,Saturation: Real);

Var
	Max,Min,Redc,Greenc,Bluec : Real;

Begin

	Max := Maximum(Red,Green,Blue);
	Min := Minimum(Red,Green,Blue);
	Lightness := (Max + Min)/2;	{Lightness}

	{ Calculate Saturation }
	If Max = Min Then {Achromatic Case}
	    Begin 
		Saturation := 0;
		Hue := 0;
	    End 
	Else 
	    Begin 		{Chromatic Case}
		if Lightness <= 0.5 Then
			Saturation := (Max - Min)/(Max + Min)
		Else
			Saturation := (Max - Min)/(2 - Max - Min);
		{Calculate Hue}
		Redc := (Max - Red)/(Max - Min);
		Greenc := (Max - Green)/(Max - Min);
		Bluec := (Max - Blue)/(Max - Min);
	        If Red = Max Then
			Hue := Bluec - Greenc
		Else If Green = Max Then
			Hue := 2 + Redc - Bluec
		Else If Blue = Max Then
			Hue := 4 + Greenc - Redc;
		Hue := Hue * 60;
		If Hue < 0.0 Then 
			Hue := Hue + 360;
	    End; {Chromatic Case}

End {RGB_to_HLS};

	
Begin

	Writeln(' ');
	Write('HLSTAB:');

	RedCount := 0;
	BlueCount := 0;
	GreenCount := 0;

	While RedCount <= 1.0 Do Begin
	    GreenCount := 0;
	    While GreenCount <= 1.00 Do Begin
		BlueCount := 0;
		While BlueCount <= 1.00 Do Begin
		    RGB_to_HLS(RedCount,
		    	       GreenCount,
			       BlueCount,
			       Hue,
	    		       Lightness,
			       Saturation);
		    Lightness := Lightness * 100;
		    Saturation := Saturation * 100;
		    Writeln('	DB	''',
				Hue:0:0,';',
				Lightness:0:0,';',
				Saturation:0:0,';',
				'''	; Red = ',(RedCount*100):0:0,',',
		    		' Green = ',(GreenCount*100):0:0,',', 
	       	    		' Blue = ',(BlueCount*100):0:0);
		    Writeln(' ');
		    BlueCount := BlueCount + 0.3333;
                End {While Blue};
		GreenCount := GreenCount + 0.3333;
	    End {While Green};
	    RedCount := RedCount + 0.3333;
	End {While Red};

End.
    
600.2Thank you!USHS01::BLANDOReality, what a concept!Mon Nov 30 1987 18:2640
    Thank you to .1

        Question, I noted the following line:

>           Red := 1;
>	    Green := 1;
>	    Blue := 1

	In HLS_to_RGB when both saturation and hue are zero, I believe
    the correct values would be:

>>          Red := Lightness;
>>	    Green := Lightness;
>>	    Blue := Lightness

    
	Also, the code you gave appears to shift RGB by 120 degrees,
    and does not agree with the VT300 manual.  To fix, shift the values 
    by 120 degrees.

>>	If Red = Max Then
>>		Hue := 2 + Bluec - Greenc
>>	Else If Green = Max Then
>>		Hue := 4 + Redc - Bluec
>>	Else
>>		Hue := Greenc - Redc;

	and

>>		Red := Value(M1,M2,Hue);
>>		Green := Value(M1,M2,Hue-120);
>>		Blue := Value(M1,M2,Hue+120);

        For those interested, let me point out that .1 user number
    from 0.0 to 1.0 for RGB values, uses 0.0 to 359.999 for Hue, and
    0.0 to 1.0 for Lightness and Saturation.
    So if you want to use number compatible with the VT manuals, you
    need to multiply all the 0.0 - 1.0 values by 100.
    
    FJBlando
600.3CSSAUS::HUNTERMonkey with a diagnostic trackMon Nov 30 1987 21:137
    
    You are probably quite correct. I wrote the program in a big hurry
    to do some conversion. The output of it may look a little odd because
    it was supposed to produce BSO assembler tables that were to go
    into the firmware for a terminal.
    
    Warwick.