Skip to content

Instantly share code, notes, and snippets.

@yoggy
Last active July 31, 2024 14:34
Show Gist options
  • Save yoggy/8999625 to your computer and use it in GitHub Desktop.
Save yoggy/8999625 to your computer and use it in GitHub Desktop.
//
// 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