如何将HSL色彩空间转换到RGB?
请问如何将色调(0-240),饱和度(0-240),亮度(0-240)着三个值
转换成0-255级RGB颜色(具体请参看windows的画图工具中的标准颜色选
择对话框),转换公式是什么?
问题点数:20、回复次数:4Top
1 楼mayax(又长又今)回复于 2006-03-21 10:07:59 得分 15
/* hsv color model */
struct hsv_t
{ union {
struct { float h , s , v; };
float c[3];
};
public:
static const size_t dimension = 3;
public:
inline hsv_t( void ) {}
inline hsv_t( const hsv_t& a ) :h(a.h),s(a.s),v(a.v) {}
inline explicit hsv_t( const color_t& cl ) { rgb2hsv( cl ); }
inline explicit hsv_t( const float& h , const float& s , const float&v ) :h(h),s(s),v(v) {}
private:
inline void rgb2hsv( const color_t& cl ) {
float ma = max( cl.r , cl.g , cl.b );
float mi = min( cl.r , cl.g , cl.b );
v = ma;
s = ( ma - mi ) / ma;
if( ma == 0 )
h = 0;
else {
float d = __rcp( ma - mi );
if( cl.r == ma )
h = ( cl.g - cl.b ) * d;
else if (cl.g == ma)
h = 2 + ( cl.b - cl.r ) * d;
else
h = 4 + ( cl.r - cl.g ) * d;
h *= 0.16666666666666666666666666666667f;
if( h < 0 )
h += 1;
}
}
inline void hsv2rgb( color_t& cl ) const {
if( s == 0 ) {
cl.r = v;
cl.g = v;
cl.b = v;
}
else {
float f , p , q , t , h;
int i;
h = static_cast< float >( fmod( h , 1 ) );
if( h < 0 )
h += 1;
h *= 6;
i = static_cast< int >( floor( h ) );
f = h - i;
p = v * ( 1 - s );
q = v * ( 1 - ( s * f ) );
t = v * ( 1 - ( s * ( 1 - f ) ) );
switch( i )
{
case 0:
cl.r = v;
cl.g = t;
cl.b = p;
break;
case 1:
cl.r = q;
cl.g = v;
cl.b = p;
break;
case 2:
cl.r = p;
cl.g = v;
cl.b = t;
break;
case 3:
cl.r = p;
cl.g = q;
cl.b = v;
break;
case 4:
cl.r = t;
cl.g = p;
cl.b = v;
break;
case 5:
cl.r = v;
cl.g = p;
cl.b = q;
break;
}
}
}
public:
template<typename _T1 , typename _T2 , typename _T3>
inline void set( const _T1& _h , const _T2& _s , const _T3& _v ) {
h = (float)_h; s = (float)_s; v = (float)_v;
}
template<typename _Ty>
inline void single( const _Ty& a ) {
h = (float)a; s = (float)a; v = (float)a;
}
inline void copy( const float a[3] ) { memcpy( c , a , sizeof(float)*3 ); }
inline void input( const color_t& rgb ) { rgb2hsv( rgb ); }
inline color_t output( void ) const { color_t rgb; hsv2rgb( rgb ); return rgb; }
};
/* hls model */
struct hls_t
{ union {
struct { float h , l , s; };
float c[3];
};
public:
static const size_t dimension = 4;
public:
inline hls_t( void ) {}
inline hls_t( const hls_t& a ) :h(a.h),l(a.l),s(a.s) {}
inline explicit hls_t( const color_t& cl ) { rgb2hls( cl ); }
inline explicit hls_t( const float& h , const float& l , const float& s ) :h(h),l(l),s(s) {}
private:
inline void rgb2hls( const color_t& cl ) {
float mi = min( cl.r , cl.g , cl.b );
float ma = max( cl.r , cl.g , cl.b );
l = ( mi + ma ) * 0.5f;
if( ma == mi ) {
h = 0;
s = 0;
}
else
{
float d = ma - mi;
if (l < 0.5f )
s = d / ( ma + mi );
else
s = d / ( 2 - ( ma + mi ) );
if( cl.r == ma )
h = ( cl.g - cl.b ) / d;
else if( cl.g == ma)
h = 2 + ( cl.b - cl.r ) / d;
else
h = 4 + ( cl.r - cl.g ) / d;
h *= 0.16666666666666666666666666666667f;
if( h < 0 )
h += 1;
}
}
inline void hls2rgb( color_t& cl ) const {
# define HueToRGB( r , m1 , m2 , h ) \
{ \
if( h < 0 ) \
h += 1; \
if( h > 1 ) \
h -= 1; \
if( 6.0 * h < 1 ) \
r = ( m1 + ( m2 - m1 ) * h * 6 ); \
else if( 2.0 * h < 1 ) \
r = m2; \
else if( 3.0 * h < 2.0 ) \
r = ( m1 + ( m2 - m1 ) * ( ( float ) ( 2.0 / 3.0 ) - h ) * 6 ); \
else \
r = m1; \
}
float m1 , m2 , h;
if( s == 0 ) {
cl.r = l;
cl.g = l;
cl.b = l;
}
else
{
if( l <= 0.5 )
m2 = l * ( 1 + s );
else
m2 = l + s - l * s;
m1 = 2 * l - m2;
h = h + 0.33333333333333333333333333333333f;
HueToRGB( cl.r , m1 , m2 , h );
h = h;
HueToRGB( cl.g , m1 , m2 , h );
h = h - 0.33333333333333333333333333333333f;
HueToRGB( cl.b , m1 , m2 , h );
}
# undef HueToRGB
}
public:
template<typename _T1 , typename _T2 , typename _T3>
inline void set( const _T1& _h , const _T2& _l , const _T3& _s ) {
h = (float)_h; l = (float)_l; s = (float)_s;
}
template<typename _Ty>
inline void single( const _Ty& a ) {
h = (float)a; l = (float)a; s = (float)a;
}
inline void copy( const float a[3] ) { memcpy( c , a , sizeof(float)*3 ); }
inline void input( const color_t& rgb ) { rgb2hls( rgb ); }
inline color_t output( void ) const { color_t rgb; hls2rgb( rgb ); return rgb; }
};
/* YIQ model */
struct yiq_t
{ union {
struct { float y , i , q; };
float c[3];
};
public:
static const size_t dimension = 3;
public:
inline yiq_t( void ) {}
inline yiq_t( const yiq_t& a ) :y(a.y),i(a.i),q(a.q) {}
inline explicit yiq_t( const color_t& cl ) { rgb2yiq( cl ); }
inline explicit yiq_t( const float& y , const float& i , const float& q ) :y(y),i(i),q(q) {}
private:
inline void rgb2yiq( const color_t& cl ) {
y = 0.299f * cl.r + 0.587f * cl.g + 0.114f * cl.b;
i = 0.596f * cl.r - 0.275f * cl.g - 0.321f * cl.b;
q = 0.212f * cl.r - 0.523f * cl.g + 0.311f * cl.b;
}
inline void yiq2rgb( color_t& cl ) const {
cl.r = y + 0.956f * i + 0.620f * q;
cl.g = y - 0.272f * i - 0.647f * q;
cl.b = y - 1.108f * i + 1.705f * q;
}
public:
template<typename _T1 , typename _T2 , typename _T3>
inline void set( const _T1& _y , const _T2& _i , const _T3& _q ) {
y = (float)_y; l = (float)_i; s = (float)_q;
}
template<typename _Ty>
inline void single( const _Ty& a ) {
y = (float)a; i = (float)a; q = (float)a;
}
inline void copy( const float a[3] ) { memcpy( c , a , sizeof(float)*3 ); }
inline void input( const color_t& rgb ) { rgb2yiq( rgb ); }
inline color_t output( void ) const { color_t rgb; yiq2rgb( rgb ); return rgb; }
};
/* CIE-XYZ model */
struct cie_t
{ union {
struct { float x , y , z; };
float c[3];
};
public:
static const size_t dimension = 3;
public:
inline cie_t( void ) {}
inline cie_t( const cie_t& s ) :x(s.x),y(s.y),z(s.z) {}
inline explicit cie_t( const color_t& cl ) { rgb2xyz( cl ); }
inline explicit cie_t( const float& x , const float& y , const float& z ) :x(x),y(y),z(z) {}
private:
inline void rgb2xyz( const color_t& cl ) {
x = 0.412453f * cl.r + 0.357580f * cl.g + 0.180423f * cl.b;
y = 0.212671f * cl.r + 0.715160f * cl.g + 0.072169f * cl.b;
z = 0.019334f * cl.r + 0.119193f * cl.g + 0.950227f * cl.b;
}
inline void xyz2rgb( color_t& cl ) const {
cl.r = 3.24079f *x - 1.537150f * y - 0.498535f * z;
cl.g = -0.969256f *x + 1.875992f * y + 0.041556f * z;
cl.b = 0.055648f *x - 0.204043f * y + 1.057311f * z;
}
public:
template<typename _T1 , typename _T2 , typename _T3>
inline void set( const _T1& _x , const _T2& _y , const _T3& _z ) {
x = (float)_x; l = (float)_y; s = (float)_z;
}
template<typename _Ty>
inline void single( const _Ty& a ) {
x = (float)a; y = (float)a; z = (float)a;
}
inline void copy( const float a[3] ) { memcpy( c , a , sizeof(float)*3 ); }
inline void input( const color_t& rgb ) { rgb2xyz( rgb ); }
inline color_t output( void ) const { color_t rgb; xyz2rgb( rgb ); return rgb; }
};Top
2 楼ricky921(ricky)回复于 2006-03-23 16:01:05 得分 5
楼上好强啊
不过建议楼主到这个网站看看
关于色彩空间变换 很全
http://www.easyrgb.com/math.php?MATH=M18Top
3 楼jasnplus(刚)回复于 2006-03-24 19:57:18 得分 0
验证了一下,确是正确的公式,
非常感谢!Top
4 楼jasnplus(刚)回复于 2006-03-24 19:58:03 得分 0
感谢回帖!Top




