-
-
Save orbitcowboy/9071b619c6ed5b0d6169280b81e73a54 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