Skip to content

Instantly share code, notes, and snippets.

@r-lyeh-archived
Created March 6, 2015 11:55
Show Gist options
  • Save r-lyeh-archived/13696e93811ba21a5aed to your computer and use it in GitHub Desktop.
Save r-lyeh-archived/13696e93811ba21a5aed to your computer and use it in GitHub Desktop.
rgb2hsl.cpp
// a few color space conversions in c++11, original code by mjijackson.com
// - rlyeh, public domain licensed.
#include <tuple>
#include <algorithm>
#include <stdint.h>
std::tuple<float,float,float> rgb2hsl( float r, float g, float b ) { // ranges: input[0..255], output[0..1]
r /= 255, g /= 255, b /= 255;
float max = std::max(std::max(r, g), b), min = std::min(std::min(r, g), b);
float h, s, l = (max + min) / 2;
if( max != min ) {
float d = max - min;
s = l > 0.5f ? d / (2 - max - min) : d / (max + min);
/**/ if(max == r) h = (g - b) / (d + (g < b ? 6 : 0));
else if(max == g) h = (b - r) / (d + 2);
else h = (r - g) / (d + 4);
return std::tuple<float,float,float>{ h / 6.f, s, l };
}
return std::tuple<float,float,float>{ 0.f, 0.f, l }; // achromatic
}
std::tuple<uint8_t,uint8_t,uint8_t> hsl2rgb( float h, float s, float l ) { // ranges: input[0..1], output[0..255]
if( s > 0 ) {
auto hue2rgb = [&](float p, float q, float t){
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1/6.f) return p + (q - p) * 6 * t;
if(t < 1/2.f) return q;
if(t < 2/3.f) return p + (q - p) * (2/3.f - t) * 6;
return p;
};
float q = l < 0.5f ? l * (1 + s) : l + s - l * s;
float p = 2 * l - q;
return std::tuple<uint8_t,uint8_t,uint8_t>{
uint8_t( 255 * hue2rgb(p, q, h + 1/3.f) ),
uint8_t( 255 * hue2rgb(p, q, h) ),
uint8_t( 255 * hue2rgb(p, q, h - 1/3.f) ) };
}
uint8_t rgb = uint8_t( 255 * l ); // achromatic
return std::tuple<uint8_t,uint8_t,uint8_t>{ rgb, rgb, rgb };
}
// usage: float h,s,l; std::tie(h,s,l) = rgb2hsl( 255, 192, 127 );
// usage: unsigned char r,g,b; std::tie(r,g,b) = hsl2rgb( 0.75f, 0.5f, 0.5f );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment