HSL To RGB for PIC Microcontrollers – and others
While the float versions of this function work wonderfully on PCs, the PIC12F, not so much. Without a math coprocessor or FPU, additional libraries are loaded to handle the floats.
This function is a port of the float function which squeezed into 1830 bytes while this fits inside into 745ish bytes with no optimizations.
This function was only verified against hues at 50% saturation and 50% lightness.
// function prototypes
void HslToRgb(uint16_t hue, uint8_t saturation, uint8_t lightness);
uint8_t AdjustLightness(uint8_t color, int lightness);
// Hue: 0-360
// Saturation: 0-100
// Lightness: 0-100
void HslToRgb(uint16_t hue, uint8_t lightness, uint8_t saturation)
{
/* based on Keenan Lidral-Porter's java function in
https://stackoverflow.com/questions/27653757/how-to-use-hsl-to-rgb-conversion-function
which is...
based on algorithm from http://en.wikipedia.org/wiki/HSL_and_HSV#Converting_to_RGB
*/
while(hue>360) hue-=360;
while(saturation>100) saturation-=100;
while(lightness>100) lightness-=100;
if (hue == 0) { r = g = b = 0; }
uint16_t chroma = (1 - abs((2 * lightness) - 100)) * saturation;
uint16_t huePrimet = hue * 10 / 6;
uint16_t huePrime = huePrimet / 100;
uint16_t fhPi = huePrimet - (huePrime * 100);
if (hue < = 59) fhPi = 100 - fhPi;
if (hue >= 120 && hue < = 179) fhPi = 100 - fhPi;
if (hue >= 240 && hue < = 299) fhPi = 100 - fhPi;
uint16_t secondComponent = (chroma * (100 - abs(fhPi))) / 100;
int red = 0, green = 0, blue = 0;
switch (huePrime)
{
case 0:
red = chroma;
green = secondComponent;
break;
case 1:
red = secondComponent;
green = chroma;
break;
case 2:
green = chroma;
blue = secondComponent;
break;
case 3:
green = secondComponent;
blue = chroma;
break;
case 4:
red = secondComponent;
blue = chroma;
break;
case 5:
red = chroma;
blue = secondComponent;
break;
}
lightness = lightness - (chroma / 2);
r = AdjustLightness(red, lightness);
g = AdjustLightness(green, lightness);
b = AdjustLightness(blue, lightness);
}
uint8_t AdjustLightness(uint8_t color, int lightness)
{
return (color + lightness) * 255 / 100;
}
Leave a Reply