Last active
July 31, 2024 14:34
-
-
Save yoggy/8999625 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// | |
// RGB to HSV convert sample | |
// | |
// see also : http://ja.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93 | |
// | |
#include <stdio.h> | |
#include <math.h> | |
#define min_f(a, b, c) (fminf(a, fminf(b, c))) | |
#define max_f(a, b, c) (fmaxf(a, fmaxf(b, c))) | |
void rgb2hsv(const unsigned char &src_r, const unsigned char &src_g, const unsigned char &src_b, unsigned char &dst_h, unsigned char &dst_s, unsigned char &dst_v) | |
{ | |
float r = src_r / 255.0f; | |
float g = src_g / 255.0f; | |
float b = src_b / 255.0f; | |
float h, s, v; // h:0-360.0, s:0.0-1.0, v:0.0-1.0 | |
float max = max_f(r, g, b); | |
float min = min_f(r, g, b); | |
v = max; | |
if (max == 0.0f) { | |
s = 0; | |
h = 0; | |
} | |
else if (max - min == 0.0f) { | |
s = 0; | |
h = 0; | |
} | |
else { | |
s = (max - min) / max; | |
if (max == r) { | |
h = 60 * ((g - b) / (max - min)) + 0; | |
} | |
else if (max == g) { | |
h = 60 * ((b - r) / (max - min)) + 120; | |
} | |
else { | |
h = 60 * ((r - g) / (max - min)) + 240; | |
} | |
} | |
if (h < 0) h += 360.0f; | |
dst_h = (unsigned char)(h / 2); // dst_h : 0-180 | |
dst_s = (unsigned char)(s * 255); // dst_s : 0-255 | |
dst_v = (unsigned char)(v * 255); // dst_v : 0-255 | |
} | |
void hsv2rgb(const unsigned char &src_h, const unsigned char &src_s, const unsigned char &src_v, unsigned char &dst_r, unsigned char &dst_g, unsigned char &dst_b) | |
{ | |
float h = src_h * 2.0f; // 0-360 | |
float s = src_s / 255.0f; // 0.0-1.0 | |
float v = src_v / 255.0f; // 0.0-1.0 | |
float r, g, b; // 0.0-1.0 | |
int hi = (int)(h / 60.0f) % 6; | |
float f = (h / 60.0f) - hi; | |
float p = v * (1.0f - s); | |
float q = v * (1.0f - s * f); | |
float t = v * (1.0f - s * (1.0f - f)); | |
switch(hi) { | |
case 0: r = v, g = t, b = p; break; | |
case 1: r = q, g = v, b = p; break; | |
case 2: r = p, g = v, b = t; break; | |
case 3: r = p, g = q, b = v; break; | |
case 4: r = t, g = p, b = v; break; | |
case 5: r = v, g = p, b = q; break; | |
} | |
dst_r = (unsigned char)(r * 255); // dst_r : 0-255 | |
dst_g = (unsigned char)(g * 255); // dst_r : 0-255 | |
dst_b = (unsigned char)(b * 255); // dst_r : 0-255 | |
} | |
void test(const unsigned &r, const unsigned &g, const unsigned &b, const unsigned &h, const unsigned &s, const unsigned &v) | |
{ | |
unsigned char rv_h, rv_s, rv_v; | |
unsigned char rv_r, rv_g, rv_b; | |
rgb2hsv(r, g, b, rv_h, rv_s, rv_v); | |
hsv2rgb(rv_h, rv_s, rv_v, rv_r, rv_g, rv_b); | |
printf("rgb(%d, %d, %d) -> hsv(%d, %d, %d) -> rgb(%d, %d, %d) ", r, g, b, rv_h, rv_s, rv_v, rv_r, rv_g, rv_b); | |
printf("\n"); | |
} | |
int main(int argc, char *argv[]) | |
{ | |
test(255, 0, 0, 0, 255, 255); | |
test(255, 255, 0, 30, 255, 255); | |
test( 0, 255, 0, 60, 255, 255); | |
test( 0, 255, 255, 90, 255, 255); | |
test( 0, 0, 255, 120, 255, 255); | |
test(255, 0, 255, 150, 255, 255); | |
test(255, 255, 255, 0, 0, 255); | |
test(128, 128, 128, 0, 0, 128); | |
test( 0, 0, 0, 0, 0, 0); | |
test(255, 128, 0, 0, 255, 255); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment