http://www.devpia.com/Maeul/Contents/Detail.aspx?BoardID=51&MAEULNO=20&no=7249&page=45
보색이란 색상휠에서 색조(hue) 값이 180도 반대방향에 위치한다고 합니다.
(어렴풋 예전 미술 시간에 배웠던 것도 같습니다.)
즉 RGB를 HSL값으로 변환한 후 HSL에서 색조(hue)를 180도 돌려준 후 이 HSL 값을 RGB 값으로 다시 변환하면 됩니다.
– 보색 구하는 함수
[code language=”cpp”]
//
// Calculate complementary color
//
// @param clr : [in] COLORREF, input RGB color from which
// complementary color is calculated
//
// @return RGB color value of complementary color of input RGB color
COLORREF CalcComplemental(COLORREF clr)
{
long hsl_h = 0, hsl_s = 0, hsl_l = 0;
RGB2HSL_(clr, hsl_h, hsl_s, hsl_l); // CONV RGB to HSL
hsl_h += 0x200; // HUE, ADD 180 deg (0x200 = 0x400 / 2)
hsl_h &= 0x7ff; // HUE, MOD 360 deg to HUE
return HSL2RGB_(hsl_h, hsl_s, hsl_l); // CONV HSL to RGB
}
[/code]
– RGB 에서 HSL 변환하는 함수
[code language=”cpp”]
//
// RGB to HSL conversion
//
// @param clr : [in] COLORREF, input RGB value to be converted
// @param hue : [out] double &, converted hue value (0 ~ 2*PI)
// @param saturation : [out] double &, converted saturation value (0%~ 100%)
// @param lightness : [out] double &, converted lightness value (0% ~ 100%)
void RGB2HSL( COLORREF clr,
double & hue,
double & saturation,
double & lightness)
{
long hsl_h = 0, hsl_s = 0, hsl_l = 0;
RGB2HSL_(clr, hsl_h, hsl_s, hsl_l);
// long to double
hue = 2.0 * 3.141592 * (double)hsl_h / 1024.0;
saturation = (double)hsl_s / 1024.0;
lightness = (double)hsl_l / 1024.0;
}
[/code]
– HSL 에서 RGB 변환하는 함수
[code language=”cpp”]
//
// HSL to RGB conversion
//
// @param hue : [in] double, input hue value (0 ~ 2*PI)
// @param saturation : [in] double, input saturation value (0% ~ 100%)
// @param lightnelss : [in] double, input lightness value (0% ~ 100%)
//
// @return converted RGB color value from the input HSL value
COLORREF HSL2RGB(double hue, double saturation, double lightness)
{
// double to long
const long hsl_h = (long)(hue / 2.0 / 3.141592 * 1024.0);
const long hsl_s = (long)(saturation * 1024.0);
const long hsl_l = (long)(lightness * 1024.0);
return HSL2RGB_(hsl_h, hsl_s, hsl_l);
}
[/code]
– 옵티마이징
[code language=”cpp”]
//
// Integer version with 2^10(1024) resolution
//
// @param hsl_h : [out] long &, hue, 0 ~ 1024
// @param hsl_s : [out] long &, saturation, 0 ~ 1024
// @param hsl_l : [out] long &, lightness, 0 ~ 1024
void RGB2HSL_(COLORREF clr, long & hsl_h, long & hsl_s, long & hsl_l)
{
const long var_r = GetRValue(clr) << 2;
const long var_g = GetGValue(clr) << 2;
const long var_b = GetBValue(clr) << 2;
const long var_min = min(var_r, min(var_g, var_b));
const long var_max = max(var_r, max(var_g, var_b));
const long del_max = var_max – var_min;
hsl_l = (var_max + var_min) >> 1;
if(del_max == 0)
{
hsl_h = hsl_s = 0;
}else
{
if(hsl_l < 512)
hsl_s = (del_max << 10) / (var_max + var_min);
else
hsl_s = (del_max << 10) / (2048 – var_max – var_min);
}
const long temp = (var_max << 9) / 3 / del_max + (del_max << 9) / del_max;
const long del_r = temp – ((var_r << 9) / 3) / del_max;
const long del_g = temp – ((var_g << 9) / 3) / del_max;
const long del_b = temp – ((var_b << 9) / 3) / del_max;
if(var_r == var_max)
hsl_h = del_b – del_g;
else if(var_g == var_max)
hsl_h = (1024 / 3) + del_r – del_b;
else if(var_b == var_max)
hsl_h = (2048 / 3) + del_g – del_r;
if(hsl_h < 0)
hsl_h += 1024;
else if(hsl_h > 1024)
hsl_h -= 1024;
}
//
// Integer version with 2^10(1024) resolution
//
// @param hsl_h : [in] long, hue, 0 ~ 1024
// @param hsl_s : [in] long, saturation, 0 ~ 1024
// @param hsl_l : [in] long, lightness, 0 ~ 1024
COLORREF HSL2RGB_(long hsl_h, long hsl_s, long hsl_l)
{
BYTE clrR = 0, clrG = 0, clrB = 0;
long var_1 = 0, var_2 = 0;
const long var_h = hsl_h;
const long var_s = hsl_s;
const long var_l = hsl_l;
if(hsl_s == 0)
clrR = clrG = clrB = (BYTE)(var_l >> 2);
else
{
if(var_l < 512)
var_2 = var_l + ((var_l * var_s) >> 10);
else
var_2 = var_l + var_s – ((var_l * var_s) >> 10);
var_1 = (var_l << 1) – var_2;
clrR = (BYTE)(HUE2RGB_(var_1, var_2, var_h + (1024 / 3)) >> 2);
clrG = (BYTE)(HUE2RGB_(var_1, var_2, var_h) >> 2);
clrB = (BYTE)(HUE2RGB_(var_1, var_2, var_h – (1024 / 3)) >> 2);
}
return RGB(clrR, clrG, clrB);
}
long HUE2RGB_(long var_1, long var_2, long var_h)
{
if(var_h < 0)
var_h += 1024;
else if(var_h > 1024)
var_h -= 1024;
const long temp1 = 3 * var_h;
if(temp1 < 512)
return (var_1 + (((3 * var_2 * var_h) >> 9) –
((3 * var_1 * var_h) >> 9)));
else if(var_h < 512)
return var_2;
else if(temp1 < 2048)
{
const long temp2 = 4096 – (temp1 << 1);
return (var_1 + ((var_2 * temp2 – var_1 * temp2) >> 10));
}
return var_1;
}
[/code]
답글 남기기