⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hsvmodel.h

📁 vc编写的
💻 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 + -