📄 hsvmodel.h
字号:
/*
Copyright (c) 1999, kSet Lab
Author: Konstantin Bukreev
E-mail: konstantin@mail.primorye.ru
Created: 29.08.99 20:54:24
Version: 1.1.0
Description: colour models
Special thanks to Ken Fishkin, John Clark Craig and Jeff Webb
*/
#ifndef _HSVModel_b31b8ca2_5e53_11d3_9285_0080adb811c5
#define _HSVModel_b31b8ca2_5e53_11d3_9285_0080adb811c5
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <math.h>
namespace
{
const float fallibility = 0.0001f;
inline bool equal (float f1, float f2)
{
return (fabs(f1 - f2) < fallibility);
}
}
class _HSVModel
{
float m_hue;
float m_sat;
float m_val;
public:
_HSVModel () throw() : m_hue(0), m_sat(0), m_val(0) {}
_HSVModel (float hue, float sat, float val) throw() : m_hue(hue), m_sat(sat), m_val(val) {}
_HSVModel (COLORREF);
void toRgb (BYTE& red, BYTE& green, BYTE& blue);
void fromRgb (BYTE red, BYTE& green, BYTE& blue);
COLORREF rgb ();
void rgb (COLORREF);
operator COLORREF ();
void set (float hue, float sat, float val) throw() {m_hue = hue; m_sat = sat; m_val = val;}
void get (float& hue, float& sat, float& val) const throw() {hue = m_hue; sat = m_sat; val = m_val;}
float hue () const throw() {return m_hue;}
void hue (float hue) throw() {m_hue = hue;}
float saturation () const throw() {return m_sat;}
void saturation (float sat) throw() {m_sat = sat;}
float value () const throw() {return m_val;}
void value (float val) throw() {m_val = val;}
static bool HSVtoRGB (float h, float s, float v, BYTE& r, BYTE& g, BYTE& b);
static bool RGBtoHSV (BYTE r, BYTE g, BYTE b, float& h, float& s, float& v);
};
inline _HSVModel::_HSVModel (COLORREF clr) throw() : m_hue(0), m_sat(0), m_val(0)
{
RGBtoHSV(GetRValue(clr), GetGValue(clr), GetBValue(clr), m_hue, m_sat, m_val);
};
inline void _HSVModel::toRgb (BYTE& red, BYTE& green, BYTE& blue)
{
HSVtoRGB(m_hue, m_sat, m_val,red, green, blue);
}
inline void _HSVModel::fromRgb (BYTE red, BYTE& green, BYTE& blue)
{
RGBtoHSV(red, green, blue, m_hue, m_sat, m_val);
}
inline COLORREF _HSVModel::rgb ()
{
BYTE r, g, b;
HSVtoRGB(m_hue, m_sat, m_val, r, g, b);
return RGB(r, g, b);
}
inline void _HSVModel::rgb (COLORREF clr)
{
RGBtoHSV(GetRValue(clr), GetGValue(clr), GetBValue(clr), m_hue, m_sat, m_val);
}
inline _HSVModel::operator COLORREF ()
{
return rgb();
}
inline bool _HSVModel::HSVtoRGB (float hue, float sat, float val, BYTE& red, BYTE& green, BYTE& blue)
{
_ASSERTE(hue <= 360.0f && hue >= 0.0f);
_ASSERTE(sat <= 100.0f && sat >= 0.0f);
_ASSERTE(val <= 100.0f && val >= 0.0f);
float fs, fv, fh, ff, fp, fq, ft, fr, fg, fb;
fs = sat / 100;
fv = val / 100;
if (equal(sat, 0.0f))
{
fb = fg = fr = fv;
}
else
{
fh = hue / 60.0f;
if (equal(fh, 6.0f))
fh = 0.0f;
int n = (int)fh;
ff = fh - n;
fp = fv * (1 - fs);
fq = fv * (1 - (fs * ff));
ft = fv * (1 - (fs * (1 - ff)));
switch (n)
{
case 0:
fr = fv; fg = ft; fb = fp;
break;
case 1:
fr = fq; fg = fv; fb = fp;
break;
case 2:
fr = fp; fg = fv; fb = ft;
break;
case 3:
fr = fp; fg = fq; fb = fv;
break;
case 4:
fr = ft; fg = fp; fb = fv;
break;
case 5:
fr = fv; fg = fp; fb = fq;
break;
default:
_ASSERT(0);
};
}
_ASSERTE (fg <= 1.0f && fg >= 0.0f);
_ASSERTE (fr <= 1.0f && fr >= 0.0f);
_ASSERTE (fb <= 1.0f && fb >= 0.0f);
red = (BYTE)(255.9999f * fr);
green = (BYTE)(255.9999f * fg);
blue = (BYTE)(255.9999f * fb);
return true;
}
inline bool _HSVModel::RGBtoHSV (BYTE red, BYTE green, BYTE blue, float& hue, float& saturation, float& value)
{
_ASSERTE(red <= 255 && red >= 0);
_ASSERTE(green <= 255 && green >= 0);
_ASSERTE(blue <= 255 && blue >= 0);
float fr, fg, fb, fMx, fMn, fv, fs, fRc, fGc, fBc;
fr = (float)red / 255.0f;
fg = (float)green / 255.0f;
fb = (float)blue / 255.0f;
fMx = max(fr, fg);
fMx = max(fMx, fb);
fMn = min(fr, fg);
fMn = min(fMn, fb);
fv = fMx;
if (!equal(fMx, .0f))
fs = (fMx - fMn) / fMx;
else
fs = .0f;
if (equal(fs, .0f))
{
hue = 0;
}
else
{
fRc = (fMx - fr) / (fMx - fMn);
fGc = (fMx - fg) / (fMx - fMn);
fBc = (fMx - fb) / (fMx - fMn);
if (equal(fMx, fr))
{
hue = fBc - fGc;
}
else if (equal(fMx, fg))
{
hue = 2 + fRc - fBc;
}
else if (equal(fMx, fb))
{
hue = 4 + fGc - fRc;
}
else
_ASSERT(0);
hue = hue * 60.0f;
if (hue < .0f)
hue = hue + 360.0f;
}
saturation = fs * 100;
value = fv * 100;
_ASSERT(hue <= 360.0f && hue >= 0.0f);
_ASSERT(saturation <= 100.0f && saturation >= 0.0f);
_ASSERT(value <= 100.0f && value >= 0.0f);
return true;
}
class _HSLModel
{
BYTE m_hue;
BYTE m_sat;
BYTE m_lum;
public:
_HSLModel () throw() : m_hue(0), m_sat(0), m_lum(0) {}
_HSLModel (BYTE hue, BYTE sat, BYTE lum) throw() : m_hue(hue), m_sat(sat), m_lum(lum) {}
_HSLModel (COLORREF);
void toRgb (BYTE& red, BYTE& green, BYTE& blue);
void fromRgb (BYTE red, BYTE& green, BYTE& blue);
COLORREF rgb ();
void rgb (COLORREF);
operator COLORREF ();
void set (BYTE hue, BYTE sat, BYTE lum) throw() {m_hue = hue; m_sat = sat; m_lum = lum;}
void get (BYTE& hue, BYTE& sat, BYTE& lum) const throw() {hue = m_hue; sat = m_sat; lum = m_lum;}
BYTE hue () const throw() {return m_hue;}
void hue (BYTE hue) throw() {m_hue = hue;}
BYTE saturation () const throw() {return m_sat;}
void saturation (BYTE sat) throw() {m_sat = sat;}
BYTE luminance () const throw() {return m_lum;}
void luminance (BYTE lum) throw() {m_lum = lum;}
static bool HSLtoRGB (BYTE h, BYTE s, BYTE l, BYTE& r, BYTE& g, BYTE& b);
static bool RGBtoHSL (BYTE r, BYTE g, BYTE b, BYTE& h, BYTE& s, BYTE& l);
};
inline _HSLModel::_HSLModel (COLORREF clr) throw() : m_hue(0), m_sat(0), m_lum(0)
{
RGBtoHSL(GetRValue(clr), GetGValue(clr), GetBValue(clr), m_hue, m_sat, m_lum);
};
inline void _HSLModel::toRgb (BYTE& red, BYTE& green, BYTE& blue)
{
HSLtoRGB(m_hue, m_sat, m_lum,red, green, blue);
}
inline void _HSLModel::fromRgb (BYTE red, BYTE& green, BYTE& blue)
{
RGBtoHSL(red, green, blue, m_hue, m_sat, m_lum);
}
inline COLORREF _HSLModel::rgb ()
{
BYTE r, g, b;
HSLtoRGB(m_hue, m_sat, m_lum, r, g, b);
return RGB(r, g, b);
}
inline void _HSLModel::rgb (COLORREF clr)
{
RGBtoHSL(GetRValue(clr), GetGValue(clr), GetBValue(clr), m_hue, m_sat, m_lum);
}
inline _HSLModel::operator COLORREF ()
{
return rgb();
}
/*
A Fast HSL-to-RGB Transform
by Ken Fishkin
from "Graphics Gems", Academic Press, 1990
*/
inline bool _HSLModel::HSLtoRGB (BYTE bh, BYTE bsl, BYTE bl, BYTE& br, BYTE& bg, BYTE& bb)
{
_ASSERTE(bh <= 240 && bh >= 0);
_ASSERTE(bsl <= 240 && bsl >= 0);
_ASSERTE(bl <= 240 && bl >= 0);
double h = bh / 240.0;
double sl = bsl / 240.0;
double l = bl / 240.0;
double b = .0; double r = .0; double g = .0;
double v = .0;
v = (l <= 0.5) ? (l * (1.0 + sl)) : (l + sl - l * sl);
if (v <= 0.0) {
r = g = b = 0.0;
} else {
double m;
double sv;
int sextant;
double fract, vsf, mid1, mid2;
m = l + l - v;
sv = (v - m ) / v;
h *= 6.0;
sextant = h;
fract = h - sextant;
vsf = v * sv * fract;
mid1 = m + vsf;
mid2 = v - vsf;
switch (sextant) {
case 0: r = v; g = mid1; b = m; break;
case 1: r = mid2; g = v; b = m; break;
case 2: r = m; g = v; b = mid1; break;
case 3: r = m; g = mid2; b = v; break;
case 4: r = mid1; g = m; b = v; break;
case 5: r = v; g = m; b = mid2; break;
default:
_ASSERTE(0);
}
}
_ASSERTE (g <= 1.0 && g >= 0.0);
_ASSERTE (r <= 1.0 && r >= 0.0);
_ASSERTE (b <= 1.0 && b >= 0.0);
br = r * 255.9999; bg = g * 255.9999; bb = b * 255.9999;
return true;
}
inline bool _HSLModel::RGBtoHSL (BYTE br, BYTE bg, BYTE bb, BYTE& bh, BYTE& bs, BYTE& bl)
{
_ASSERTE(br <= 255 && br >= 0);
_ASSERTE(bg <= 255 && bg >= 0);
_ASSERTE(bb <= 255 && bb >= 0);
double r = br / 255.0;
double g = bg / 255.0;
double b = bb / 255.0;
double h = 0; double s = 0; double l = 0;
double v, m, vm;
double r2, g2, b2;
v = max(r,g);
v = max(v,b);
m = min(r,g);
m = min(m,b);
if ((l = (m + v) / 2.0) <= 0.0)
goto exit;
if ((s = vm = v - m) > 0.0) {
s /= (l <= 0.5) ? (v + m ) :
(2.0 - v - m) ;
} else
goto exit;
r2 = (v - r) / vm;
g2 = (v - g) / vm;
b2 = (v - b) / vm;
if (r == v)
h = (g == m ? 5.0 + b2 : 1.0 - g2);
else if (g == v)
h = (b == m ? 1.0 + r2 : 3.0 - b2);
else
h = (r == m ? 3.0 + g2 : 5.0 - r2);
h /= 6;
exit:
_ASSERTE (h <= 1.0 && h >= 0.0);
_ASSERTE (l <= 1.0 && l >= 0.0);
_ASSERTE (s <= 1.0 && s >= 0.0);
bh = h == 1.0 ? 0 : h * 240.9999;
bl = l * 240.9999;
bs = s * 240.9999;
return true;
}
#endif //_HSVModel_b31b8ca2_5e53_11d3_9285_0080adb811c5
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -