Last active
December 1, 2022 22:18
-
-
Save marukrap/7c361f2c367eaf40537a8715e3fd952a to your computer and use it in GitHub Desktop.
Simple Color Conversions between RGB and HSL/HSV
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://en.wikipedia.org/wiki/HSL_and_HSV | |
#include <SFML/Graphics/Color.hpp> | |
#include <tuple> | |
#include <algorithm> // min, max | |
// HSL/HSV | |
// H Hue component, range: [0.f, 360.f) | |
// S Saturation component, range: [0.f, 1.f) | |
// L Lightness component, range: [0.f, 1.f) | |
// V Value component, range: [0.f, 1.f) | |
// sf::Color | |
// r Red component, range: [0, 255] | |
// g Green component, range: [0, 255] | |
// b Blue component, range: [0, 255] | |
std::tuple<float, float, float> RGBtoHSL(const sf::Color& color) | |
{ | |
float R = color.r / 255.f; | |
float G = color.g / 255.f; | |
float B = color.b / 255.f; | |
float M = std::max({ R, G, B }); | |
float m = std::min({ R, G, B }); | |
float C = M - m; // Chroma | |
float H = 0.f; // Hue | |
float S = 0.f; // Saturation | |
float L = 0.f; // Lightness | |
if (C != 0.f) | |
{ | |
if (M == R) | |
H = std::fmod(((G - B) / C), 6.f); | |
else if (M == G) | |
H = ((B - R) / C) + 2; | |
else if (M == B) | |
H = ((R - G) / C) + 4; | |
H *= 60; | |
} | |
if (H < 0.f) | |
H += 360; | |
L += (M + m) / 2; | |
if (L != 1.f && L != 0.f) | |
S = C / (1 - std::fabs(2 * L - 1)); | |
return { H, S, L }; | |
} | |
std::tuple<float, float, float> RGBtoHSV(const sf::Color& color) | |
{ | |
float R = color.r / 255.f; | |
float G = color.g / 255.f; | |
float B = color.b / 255.f; | |
float M = std::max({ R, G, B }); | |
float m = std::min({ R, G, B }); | |
float C = M - m; // Chroma | |
float H = 0.f; // Hue | |
float S = 0.f; // Saturation | |
float V = 0.f; // Value | |
if (C != 0.f) | |
{ | |
if (M == R) | |
H = std::fmod(((G - B) / C), 6.f); | |
else if (M == G) | |
H = ((B - R) / C) + 2; | |
else if (M == B) | |
H = ((R - G) / C) + 4; | |
H *= 60; | |
} | |
if (H < 0.f) | |
H += 360; | |
V = M; | |
if (V != 0.f) | |
S = C / V; | |
return { H, S, V }; | |
} | |
sf::Color HSLtoRGB(float H, float S, float L) | |
{ | |
float C = (1 - std::fabs(2 * L - 1)) * S; // Chroma | |
float HPrime = H / 60; // H' | |
float X = C * (1 - std::fabs(std::fmod(HPrime, 2.f) - 1)); | |
float M = L - C / 2; | |
float R = 0.f; | |
float G = 0.f; | |
float B = 0.f; | |
switch (static_cast<int>(HPrime)) | |
{ | |
case 0: R = C; G = X; break; // [0, 1) | |
case 1: R = X; G = C; break; // [1, 2) | |
case 2: G = C; B = X; break; // [2, 3) | |
case 3: G = X; B = C; break; // [3, 4) | |
case 4: R = X; B = C; break; // [4, 5) | |
case 5: R = C; B = X; break; // [5, 6) | |
} | |
R += M; | |
G += M; | |
B += M; | |
sf::Color color; | |
color.r = static_cast<sf::Uint8>(std::round(R * 255)); | |
color.g = static_cast<sf::Uint8>(std::round(G * 255)); | |
color.b = static_cast<sf::Uint8>(std::round(B * 255)); | |
return color; | |
} | |
sf::Color HSVtoRGB(float H, float S, float V) | |
{ | |
float C = S * V; // Chroma | |
float HPrime = std::fmod(H / 60, 6.f); // H' | |
float X = C * (1 - std::fabs(std::fmod(HPrime, 2.f) - 1)); | |
float M = V - C; | |
float R = 0.f; | |
float G = 0.f; | |
float B = 0.f; | |
switch (static_cast<int>(HPrime)) | |
{ | |
case 0: R = C; G = X; break; // [0, 1) | |
case 1: R = X; G = C; break; // [1, 2) | |
case 2: G = C; B = X; break; // [2, 3) | |
case 3: G = X; B = C; break; // [3, 4) | |
case 4: R = X; B = C; break; // [4, 5) | |
case 5: R = C; B = X; break; // [5, 6) | |
} | |
R += M; | |
G += M; | |
B += M; | |
sf::Color color; | |
color.r = static_cast<sf::Uint8>(std::round(R * 255)); | |
color.g = static_cast<sf::Uint8>(std::round(G * 255)); | |
color.b = static_cast<sf::Uint8>(std::round(B * 255)); | |
return color; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you very much, it would have been a big headache to write it myself