下方代码可直接编译测试
#include <stdio.h>
// #define RAND_MAX_ONE //h:0-360 s:0-1 v:0-1 非百分比
#define RAND_MAX_HUNDRED //h:0-360 s:0-100 v:0-100 百分比
#define MAX(R,G,B) (((R)>(G))?(((R)>(B))?(R):(B)):(((G)>(B))?(G):(B)))
#define MIN(R,G,B) (((R)<(G))?(((R)<(B))?(R):(B)):(((G)<(B))?(G):(B)))
typedef struct{
double h;
double s;
double v;
}hsv_t;
typedef struct{
double h;
double s;
double l;
}hsl_t;
typedef struct{
unsigned char r;
unsigned char g;
unsigned char b;
}rgb_t;
/*
* @brief RGB -> HSV
*
* @param [in] rgb 输入参数rgb
* @param [in] hsv 输出参数hsv
*
* @return None
*/
void rgb_2_hsv(hsv_t *hsv,rgb_t *rgb)
{
double rr,gg,bb;
double max,min,des;
rr = (double)rgb->r;
gg = (double)rgb->g;
bb = (double)rgb->b;
max = MAX(rr,gg,bb);
min = MIN(rr,gg,bb);
des = max - min;
if(des != 0) //max != min
{
if(rr == max)
{
hsv->h = (gg-bb)/des;
}
else if(gg == max)
{
hsv->h = (bb - rr)/des + 2;
}
else if(bb == max)
{
hsv->h = (rr - gg)/des + 4;
}
#if defined RAND_MAX_ONE
hsv->s = des / max;
#elif defined RAND_MAX_HUNDRED
hsv->s = des / max * 100;
#endif
}
else if(max != 0) //max=min && max!=0
{
#if defined RAND_MAX_ONE
hsv->s = des / max;
#elif defined RAND_MAX_HUNDRED
hsv->s = des / max *100;
#endif
}
else //max=min && max=0
{
hsv->h = hsv->s = 0;
}
hsv->h *= 60;
if(hsv->h < 0)
{
hsv->h += 360;
}
#if defined RAND_MAX_ONE
hsv->v = max / 255.0f;
#elif defined RAND_MAX_HUNDRED
hsv->v = max / 255.0f * 100;
#endif
}
/*
* @brief HSV -> RGB
*
* @param [in] hsv 输入参数hsv
* @param [in] rgb 输出参数rgb
*
* @return None
*/
void hsv_2_rgb(hsv_t *hsv,rgb_t *rgb)
{
int i = ((int)(hsv->h/60)%6);
double f = hsv->h/60 - i;
double r,g,b,p,q,t,v,s;
#if defined RAND_MAX_ONE
v = hsv->v;
s = hsv->s;
#elif defined RAND_MAX_HUNDRED
v = hsv->v / 100;
s = hsv->s / 100;
#endif
p = v * (1 - s);
q = v * (1 - f * s);
t = v * (1 - (1 - f) * s);
switch(i)
{
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;
default:
break;
}
rgb->r = r * 255;
rgb->g = g * 255;
rgb->b = b * 255;
}
/*
* @brief RGB -> HSL
*
* @param [in] rgb 输入参数rgb
* @param [in] hsl 输出参数hsl
*
* @return None
*/
void rgb_2_hsl(hsl_t *hsl,rgb_t *rgb)
{
double rr,gg,bb;
double max,min,des;
rr = (double)rgb->r;
gg = (double)rgb->g;
bb = (double)rgb->b;
max = MAX(rr,gg,bb);
min = MIN(rr,gg,bb);
des = max - min;
hsl->l = (max + min) / 2 / 255.0f;
if(des != 0) //max != min
{
if(rr == max)
{
hsl->h = (gg-bb)/des;
}
else if(gg == max)
{
hsl->h = (bb - rr)/des + 2;
}
else if(bb == max)
{
hsl->h = (rr - gg)/des + 4;
}
if(hsl->l <= 0.5)
{
hsl->s = des / (2 * hsl->l) / 255.0f;
}
else
{
hsl->s = des / (2 - (2 * hsl->l)) / 255.0f;
}
}
else //max=min
{
hsl->h = hsl->s = 0;
}
hsl->h *= 60;
if(hsl->h < 0)
{
hsl->h += 360;
}
#if defined RAND_MAX_HUNDRED
hsl->s *= 100;
hsl->l *= 100;
#endif
}
/*
* @brief HSL转RGB
*
* @param [in] temp1 输入参数r,g,b
* @param [in] temp2 输入参数p
* @param [in] temp3 输入参数q
*
* @return None
*/
void hsl_2_rgb_value(double *temp1,double *temp2,double *temp3)
{
if(*temp1 < 0)
{
*temp1 += 1.0;
}
else if(*temp1 > 1)
{
*temp1 -= 1.0;
}
if(*temp1*6.0 < 1.0)
{
*temp1 = *temp2 + ((*temp3 - *temp2) * 6 * (*temp1));
}
else if(*temp1 * 2.0 < 1.0)
{
*temp1 = *temp3;
}
else if(*temp1 * 3.0 < 2)
{
*temp1 = *temp2 + ((*temp3- *temp2) * 6 * ((2 / 3) - *temp1));
}
else
{
*temp1 = *temp2;
}
}
/*
* @brief HSL -> RGB
*
* @param [in] hsl 输入参数hsl
* @param [in] rgb 输出参数rgb
*
* @return None
*/
void hsl_2_rgb(hsl_t *hsl,rgb_t *rgb)
{
double q,p,h,l,s,r,g,b;
#if defined RAND_MAX_ONE
l = hsl->l;
s = hsl->s;
#elif defined RAND_MAX_HUNDRED
l = hsl->l / 100;
s = hsl->s / 100;
#endif
if(s == 0)
{
rgb->r = rgb->g = rgb->b = l * 255;
}
else
{
if(l < 0.5)
{
q = l * (1 + s);
}
else
{
q = l + s - (l * s);
}
p = 2 * l - q;
h = hsl->h / 360; //h规范化到[0,1]内
r = h + (1.0 / 3.0);
g = h;
b = h - (1.0 / 3.0);
hsl_2_rgb_value(&r,&p,&q);
hsl_2_rgb_value(&g,&p,&q);
hsl_2_rgb_value(&b,&p,&q);
rgb->r = r * 255;
rgb->g = g * 255;
rgb->b = b * 255;
}
}
int main()
{
rgb_t rgbTemp = {255,255,255};
hsv_t hsvTemp = {0};
hsl_t hslTemp = {0};
rgb_2_hsv(&hsvTemp,&rgbTemp);
printf("%f %f %f\n",hsvTemp.h,hsvTemp.s,hsvTemp.v);
hsv_2_rgb(&hsvTemp,&rgbTemp);
printf("%d %d %d\n",rgbTemp.r,rgbTemp.g,rgbTemp.b);
rgb_2_hsl(&hslTemp,&rgbTemp);
printf("%f %f %f\n",hslTemp.h,hslTemp.s,hslTemp.l);
hsl_2_rgb(&hslTemp,&rgbTemp);
printf("%d %d %d\n",rgbTemp.r,rgbTemp.g,rgbTemp.b);
return 0;
}
本文详细介绍RGB、HSV及HSL色彩空间之间的相互转换方法,并提供C语言实现代码。通过具体实例展示了不同色彩空间的特点及其应用场景。
4532

被折叠的 条评论
为什么被折叠?



