I have put this code together from bit's found on the internet. It converts a RGB colour to a HSL colour and back again. It prints to the serial monitor the input and the output, both RGB. It uses structs to hold the colours. It works ish. I have it set on a loop from 0-255, i can set R,G or B to i or set any one of them as a static value and cycle through the loop to see how well it converts. Depending on the various ways you could arrange that the conversion goes from perfect to not so perfect. i would like it to be perfect if possible. Can anybody help
#include "RGBHSL.h"
void setup() {
Serial.begin(9600);
}
void loop() {
for (int i=0;i<256;i++){
Buffer.Red=88; // trying difrent values or i to see how well it converts the color space
Buffer.Green=67;
Buffer.Blue=i;
Serial.println(" ");
Serial.println("***********************");
Serial.print(int(Buffer.Red));
Serial.print(" ");
Serial.print(int(Buffer.Green));
Serial.print(" ");
Serial.print(int(Buffer.Blue));
Serial.println(" ");
// RGB_HSL(Buffer.Red,Buffer.Green,Buffer.Green);
/* Serial.println(" output HSL = ");
Serial.print(int(RGB_HSL(Buffer.Red,Buffer.Green,Buffer.Blue).Hue));
Serial.print(" ");
Serial.print(int(RGB_HSL(Buffer.Red,Buffer.Green,Buffer.Blue).Sat));
Serial.print(" ");
Serial.print(int(RGB_HSL(Buffer.Red,Buffer.Green,Buffer.Blue).Lig));
Serial.print(" ");
Serial.println(" "); */
hslbuffer=RGB_HSL(Buffer.Red,Buffer.Green,Buffer.Blue);
Buffer2=HSL_RGB(RGB_HSL(Buffer.Red,Buffer.Green,Buffer.Blue));
Serial.println(" ");
Serial.print(int(Buffer2.Red));
Serial.print(" ");
Serial.print(int(Buffer2.Green));
Serial.print(" ");
Serial.print(int(Buffer2.Blue));
Serial.print(" ");
Serial.println(" ");
}
delay(1000);
}
#ifndef RGBHSL.H
#define RGBHSL.H
#include "WProgram.h"
struct ColourNoAlpha
{
byte Red;
byte Green;
byte Blue;
};
struct HSLColour{
byte Hue;
byte Sat;
byte Lig;
};
ColourNoAlpha Buffer,Buffer2;
HSLColour hslbuffer;
HSLColour RGB_HSL(byte R,byte G,byte B){
HSLColour Output;
float var_R = ( R / 255.0f );
float var_G = ( G / 255.0f );
float var_B = ( B / 255.0f );
float S;
float H;
float L;
float var_Min = min( var_R, var_G);
var_Min= min(var_Min,var_B);
float var_Max = max( var_R, var_G );//Max. value of RGB
var_Max = max(var_Max, var_B);
float del_Max = var_Max - var_Min;
L =( var_Max + var_Min ) / 2.0f; // convert to byte here
if ( del_Max == 0 ) //This is a gray, no chroma...
{
H = 0.0f; //HSL results from 0 to 1
S = 0.0f;
}
else //Chromatic data...
{
if ( L < 0.5 ) {S = del_Max / ( var_Max + var_Min );}
else { S = del_Max / ( 2.0f - var_Max - var_Min );}
float del_R = (( ( ( var_Max - var_R ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max);
float del_G = (( ( ( var_Max - var_G ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max);
float del_B = (( ( ( var_Max - var_B ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max);
if ( var_R == var_Max ) {H = del_B - del_G;}
else {if ( var_G == var_Max ) {H = ( 1.0f / 3.0f ) + del_R - del_B;}
else {if ( var_B == var_Max ){ H = ( 2.0f / 3.0f ) + del_G - del_R;}}}
if ( H < 0 ) H += 1.0f;
if ( H > 1 ) H -= 1.0f;
}
Output.Hue=byte((H*255.0f)+0.5f);
Output.Sat=byte((S*255.0f)+0.5f);
Output.Lig=byte((L*255.0f)+0.5f);
return(Output);
}
/////////////
float Hue_2_RGB(float v1,float v2,float vH){
if ( vH < 0 ) vH += 1.0f;
if ( vH > 1 ) vH -= 1.0f;
if ( ( 6.0f * vH ) < 1 ) {return ( v1 + ( v2 - v1 ) * 6.0f * vH );}
if ( ( 2.0f * vH ) < 1 ) {return ( v2 );}
if ( ( 3.0f * vH ) < 2 ) {return ( v1 + ( v2 - v1 ) * ( ( 2.0f / 3.0f ) - vH ) * 6.0f );}
return ( v1 );
}
///////////////
ColourNoAlpha HSL_RGB(HSLColour Input){ // gets a HSLColour
ColourNoAlpha Output;
float R,G,B;
float var_1,var_2;
float H,L,S;
L=float(Input.Lig/255.0f);
H=float(Input.Hue/255.0f);
S=float(Input.Sat/255.0f);
if ( S == 0 ) //HSL from 0 to 1
{
R = L * 255.0f; //RGB results from 0 to 255
G = L * 255.0f;
B = L * 255.0f;
}
else
{
if ( L < 0.5f ) {var_2 = L * ( 1 + S );}
else {var_2 = ( L + S ) - ( S * L );}
var_1 = 2.0f * L - var_2;
R = 255.0f * Hue_2_RGB( var_1, var_2, H + ( 1.0f / 3.0f ) );
G = 255.0f * Hue_2_RGB( var_1, var_2, H );
B = 255.0f * Hue_2_RGB( var_1, var_2, H - ( 1.0f / 3.0f ) );
}
Output.Red=byte(R+0.5f);
Output.Green=byte(G+0.5f);
Output.Blue=byte(B+0.5f);
return(Output);
}
#endif