In order to understand this article you should probably read this article first:
If you are curious about the theory behind the HSV and RGB color spaces, you can read this articles:
1. RGB to HSV Conversion
This function will create a HSV model from a RGB model. The algorithm behind the conversion is described by the formulas below.
|
RGB to HSV algorithm |
The meaning of the variables:
M - the RGB component with the greatest value
m - the RGB component with the smalles value
c - chroma
r,g,b - the components of the RGB model (red, green, blue)
h,s,v - the components of HSV model (hue, saturation, value)
The components of the RGB model (r,g,b), saturation (s) and value (v) should have values in the range [0,1], while the hue (h) should have values in the rnage [0,360].
The prototype of the function is:
/* Description:
* Creates a HsvColor structure from RGB components
* Parameters:
* r,g,b - the components of an RGB model expressed
* as real numbers
* Returns:
* A pointer to the HsvColor is the parameters are
* correct. Otherwise returns NULL.
*/
HsvColor* Hsv_CreateFromRgbF(double r, double g, double b);
The function can be implemented as:
HsvColor* Hsv_CreateFromRgbF(double r, double g, double b)
{
double M = 0.0, m = 0.0, c = 0.0;
HsvColor* color = NULL;
if (RgbF_IsValid(r, g, b) == true)
{
color = Hsv_Create(0.0, 0.0, 0.0);
M = Double_GetMaximum(r, g, b);
m = Double_GetMinimum(r, g, b);
c = M - m;
color->V = M;
if (c != 0.0f)
{
if (M == r)
{
color->H = fmod(((g - b) / c), 6.0);
}
else if (M == g)
{
color->H = (b - r) / c + 2.0;
}
else /*if(M==b)*/
{
color->H = (r - g) / c + 4.0;
}
color->H *= 60.0;
color->S = c / color->V;
}
}
return color;
}
2.HSV to RGB Conversion
This function will create a RGB model from a HSV model. The algorithm behind the conversion is described by the formulas below.
|
HSV to RGB algorithm |
The meaning of the variables:
c - chroma
m - the RGB component with the smalles value
x - an intermediate value used for computing the RGB model
r,g,b - the components of the RGB model (red, green, blue)
h,s,v - the components of HSV model (hue, saturation, value)
The components of the RGB model (r,g,b), saturation (s) and value (v) should have values in the range [0,1], while the hue (h) should have values in the rnage [0,360].
The prototype of the function is:
/*
* Description:
* Creates a RgbFColor structure from HSV components
* Parameters:
* h,s,v - the components of an HSV model expressed
* as real numbers
* Returns:
* A pointer to the RgbFColor is the parameters are
* correct. Otherwise returns NULL.
*/
RgbFColor* RgbF_CreateFromHsv(double h, double s, double v);
The function can be implemented as:
HsvColor* Hsv_CreateFromRgbF(double r, double g, double b)
{
double M = 0.0, m = 0.0, c = 0.0;
HsvColor* color = NULL;
if (RgbF_IsValid(r, g, b) == true)
{
color = Hsv_Create(0.0, 0.0, 0.0);
M = Double_GetMaximum(r, g, b);
m = Double_GetMinimum(r, g, b);
c = M - m;
color->V = M;
if (c != 0.0f)
{
if (M == r)
{
color->H = fmod(((g - b) / c), 6.0);
}
else if (M == g)
{
color->H = (b - r) / c + 2.0;
}
else /*if(M==b)*/
{
color->H = (r - g) / c + 4.0;
}
color->H *= 60.0;
color->S = c / color->V;
}
}
return color;
}
The function can be implemented as:
RgbFColor* RgbF_CreateFromHsv(double h, double s, double v)
{
double c = 0.0, m = 0.0, x = 0.0;
RgbFColor *color = NULL;
if (Hsv_IsValid(h, s, v) == true)
{
c = v * s;
x = c * (1.0 - fabs(fmod(h / 60.0, 2) - 1.0));
m = v - c;
if (h >= 0.0 && h < 60.0)
{
color = RgbF_Create(c + m, x + m, m);
}
else if (h >= 60.0 && h < 120.0)
{
color = RgbF_Create(x + m, c + m, m);
}
else if (h >= 120.0 && h < 180.0)
{
color = RgbF_Create(m, c + m, x + m);
}
else if (h >= 180.0 && h < 240.0)
{
color = RgbF_Create(m, x + m, c + m);
}
else if (h >= 240.0 && h < 300.0)
{
color = RgbF_Create(x + m, m, c + m);
}
else if (h >= 300.0 && h < 360.0)
{
color = RgbF_Create(c + m, m, x + m);
}
else
{
color = RgbF_Create(m, m, m);
}
}
return color;
}
3.Example
#include<stdio.h>
#include"colorspace.h"
int main(int argc, char** argv)
{
HsvColor* hsv = NULL;
RgbFColor* rgbF = NULL;
RgbIColor* rgbI = NULL;
/*HSI to RGB*/
hsv = Hsv_Create(240.5, 0.316, 0.721);
rgbF = RgbF_CreateFromHsv(hsv->H, hsv->S, hsv->V);
rgbI = RgbI_CreateFromRealForm(rgbF->R, rgbF->G, rgbF->B);
printf("\nHSV : %f %f %f", hsv->H, hsv->S, hsv->V);
printf("\nRGBf : %f %f %f", rgbF->R, rgbF->G, rgbF->B);
printf("\nRGBi : %d %d %d", rgbI->R, rgbI->G, rgbI->B);
/*Frees the resources*/
free(hsv);
free(rgbF);
free(rgbI);
/*RGB to HSI*/
rgbI = RgbI_Create(108U, 198U, 78U);
rgbF = RgbF_CreateFromIntegerForm(rgbI->R, rgbI->G, rgbI->B);
hsv = Hsv_CreateFromRgbF(rgbF->R, rgbF->G, rgbF->B);
printf("\nHSV : %f %f %f", hsv->H, hsv->S, hsv->V);
printf("\nRGBf : %f %f %f", rgbF->R, rgbF->G, rgbF->B);
printf("\nRGBi : %d %d %d", rgbI->R, rgbI->G, rgbI->B);
return 0;
}
/*Output:
HSV : 240.500000 0.316000 0.721000
RGBf : 0.495063 0.493164 0.721000
RGBi : 126 126 184
HSV : 105.000000 0.606061 0.776471
RGBf : 0.423529 0.776471 0.305882
RGBi : 108 198 78
*/