📄 bcgpdrawmanager.cpp
字号:
}
dcMem.SelectObject (pOldBmp);
DeleteObject (hmbpDib);
return TRUE;
}
// ==================================================================
//
// FUNCTION : static void SetAlphaPixel ()
//
// * Description : Draws an alpha blended pixel
//
// * Author : [Timo Hummel], Created : [8/11/99 5:04:38 PM]
//
// * Function parameters :
// [pBits] - The DIB bits
// [x] - X-Coordinate
// [y] - Y-Coordinate
// [percent] - Percentage to blit (100 = hollow, 0 = solid)
//
// ==================================================================
inline void CBCGPDrawManager::SetAlphaPixel (COLORREF* pBits,
CRect rect, int x, int y,
int percent, int m_iShadowSize,
COLORREF clrBase)
{
// Our direct bitmap access swapped the y coordinate...
y = (rect.Height()+m_iShadowSize)- y;
COLORREF* pColor = (COLORREF*) (pBits + (rect.Width () + m_iShadowSize) * y + x);
*pColor = PixelAlpha (*pColor, percent);
if (clrBase == (COLORREF)-1)
{
return;
}
*pColor = RGB ( min (255, (GetRValue (*pColor) + GetBValue (clrBase)) / 2),
min (255, (GetGValue (*pColor) + GetGValue (clrBase)) / 2),
min (255, (GetBValue (*pColor) + GetRValue (clrBase)) / 2));
}
// ==================================================================
//
// FUNCTION : PixelAlpha ()
//
// * Description : Shades a color value with a specified percentage
//
// * Author : [Timo Hummel], Created : [8/11/99 2:37:04 PM]
//
// * Returns : [COLORREF] - The result pixel
//
// * Function parameters :
// [srcPixel] - The source pixel
// [percent] - Percentage (amount of shadow)
//
// Example: percent = 10 makes the pixel around 10 times darker
// percent = 50 makes the pixel around 2 times darker
//
// ==================================================================
COLORREF CBCGPDrawManager::PixelAlpha (COLORREF srcPixel, int percent)
{
// My formula for calculating the transpareny is as
// follows (for each single color):
//
// percent
// destPixel = sourcePixel * ( ------- )
// 100
//
// This is not real alpha blending, as it only modifies the brightness,
// but not the color (a real alpha blending had to mix the source and
// destination pixels, e.g. mixing green and red makes yellow).
// For our nice "menu" shadows its good enough.
COLORREF clrFinal = RGB ( min (255, (GetRValue (srcPixel) * percent) / 100),
min (255, (GetGValue (srcPixel) * percent) / 100),
min (255, (GetBValue (srcPixel) * percent) / 100));
// TRACE ("%d %d %d\n", GetRValue (clrFinal), GetGValue (clrFinal), GetBValue (clrFinal));
return (clrFinal);
}
static inline int AdjustChannel (int nValue, double nPercent)
{
int nNewValue = (int) (.5 + nPercent * nValue);
if (nValue == 0 && nPercent > 1.)
{
nNewValue = (int) (.5 + (nPercent - 1.) * 255);
}
return min (nNewValue, 255);
}
COLORREF CBCGPDrawManager::PixelAlpha (COLORREF srcPixel, double percentR, double percentG, double percentB)
{
COLORREF clrFinal = RGB ( AdjustChannel (GetRValue (srcPixel), percentR),
AdjustChannel (GetGValue (srcPixel), percentG),
AdjustChannel (GetBValue (srcPixel), percentB));
return (clrFinal);
}
// ==================================================================
//
// FUNCTION : PixelAlpha ()
//
// * Description : Shades a color value with a specified percentage
//
// * Author : [Guillaume Nodet]
//
// * Returns : [COLORREF] - The result pixel
//
// * Function parameters :
// [srcPixel] - The source pixel
// [dstPixel] - The destination pixel
// [percent] - Percentage (amount of shadow)
//
// ==================================================================
COLORREF CBCGPDrawManager::PixelAlpha (COLORREF srcPixel, COLORREF dstPixel, int percent)
{
int ipercent = 100 - percent;
COLORREF clrFinal = RGB ( (GetRValue (srcPixel) * percent + GetRValue (dstPixel) * ipercent) / 100,
(GetGValue (srcPixel) * percent + GetGValue (dstPixel) * ipercent) / 100,
(GetBValue (srcPixel) * percent + GetBValue (dstPixel) * ipercent) / 100);
return (clrFinal);
}
void CBCGPDrawManager::SetPixel (COLORREF* pBits, int cx, int cy, int x, int y,
COLORREF color)
{
// Our direct bitmap access swapped the y coordinate...
y = cy - y;
COLORREF* pColor = (COLORREF*) (pBits + cx * y + x);
*pColor = RGB (GetBValue(color), GetGValue(color), GetRValue(color));
}
//----------------------------------------------------------------------
// Conversion between the HSL (Hue, Saturation, and Luminosity)
// and RBG color model.
//----------------------------------------------------------------------
// The conversion algorithms presented here come from the book by
// Fundamentals of Interactive Computer Graphics by Foley and van Dam.
// In the example code, HSL values are represented as floating point
// number in the range 0 to 1. RGB tridrants use the Windows convention
// of 0 to 255 of each element.
//----------------------------------------------------------------------
double CBCGPDrawManager::HuetoRGB(double m1, double m2, double h )
{
if( h < 0 ) h += 1.0;
if( h > 1 ) h -= 1.0;
if( 6.0*h < 1 )
return (m1+(m2-m1)*h*6.0);
if( 2.0*h < 1 )
return m2;
if( 3.0*h < 2.0 )
return (m1+(m2-m1)*((2.0/3.0)-h)*6.0);
return m1;
}
BYTE CBCGPDrawManager::HueToRGB(float rm1, float rm2, float rh)
{
if (rh > 360.0f)
rh -= 360.0f;
else if (rh < 0.0f)
rh += 360.0f;
if (rh < 60.0f)
rm1 = rm1 + (rm2 - rm1) * rh / 60.0f;
else if (rh < 180.0f)
rm1 = rm2;
else if (rh < 240.0f)
rm1 = rm1 + (rm2 - rm1) * (240.0f - rh) / 60.0f;
return static_cast<BYTE>(rm1 * 255);
}
COLORREF CBCGPDrawManager::HLStoRGB_ONE( double H, double L, double S )
{
double r, g, b;
double m1, m2;
if(S==0) {
r=g=b=L;
} else {
if(L <=0.5)
m2 = L*(1.0+S);
else
m2 = L+S-L*S;
m1 = 2.0*L-m2;
r = HuetoRGB(m1, m2, H+1.0/3.0);
g = HuetoRGB(m1, m2, H);
b = HuetoRGB(m1, m2, H-1.0/3.0);
}
return RGB((BYTE)(r*255), (BYTE)(g*255), (BYTE)(b*255));
}
COLORREF CBCGPDrawManager::HLStoRGB_TWO( double H, double L, double S)
{
WORD R, G, B; // RGB component values
if (S == 0.0)
R = G = B = unsigned char(L * 255.0);
else
{
float rm1, rm2;
if (L <= 0.5f)
rm2 = (float)(L + L * S);
else
rm2 = (float)(L + S - L * S);
rm1 = (float)(2.0f * L - rm2);
R = HueToRGB(rm1, rm2, (float)(H + 120.0f));
G = HueToRGB(rm1, rm2, (float)(H));
B = HueToRGB(rm1, rm2, (float)(H - 120.0f));
}
return RGB(R, G, B);
}
void CBCGPDrawManager::RGBtoHSL( COLORREF rgb, double *H, double *S, double *L )
{
double delta;
double r = (double)GetRValue(rgb)/255;
double g = (double)GetGValue(rgb)/255;
double b = (double)GetBValue(rgb)/255;
double cmax = max(r, max(g, b));
double cmin = min(r, min(g, b));
*L=(cmax+cmin)/2.0;
if(cmax==cmin)
{
*S = 0;
*H = 0; // it's really undefined
}
else
{
if(*L < 0.5)
*S = (cmax-cmin)/(cmax+cmin);
else
*S = (cmax-cmin)/(2.0-cmax-cmin);
delta = cmax - cmin;
if(r==cmax)
*H = (g-b)/delta;
else if(g==cmax)
*H = 2.0 +(b-r)/delta;
else
*H=4.0+(r-g)/delta;
*H /= 6.0;
if(*H < 0.0)
*H += 1;
}
}
void CBCGPDrawManager::RGBtoHSV (COLORREF rgb, double *H, double *S, double *V)
// Algoritm by A. R. Smith
{
double r = (double) GetRValue (rgb) / 255;
double g = (double) GetGValue (rgb) / 255;
double b = (double) GetBValue (rgb) / 255;
double dblMin = min (r, min (g, b));
double dblMax = max (r, max (g, b));
*V = dblMax; // v
double delta = dblMax - dblMin;
if( dblMax != 0 )
*S = delta / dblMax; // s
else {
// r = g = b = 0 // s = 0, v is undefined
*S = 0;
*H = -1;
return;
}
if (delta == 0.)
{
*H = 1;
}
else
{
if (r == dblMax)
*H = (g - b) / delta; // between yellow & magenta
else if( g == dblMax )
*H = 2 + ( b - r ) / delta; // between cyan & yellow
else
*H = 4 + ( r - g ) / delta; // between magenta & cyan
}
*H *= 60; // degrees
if (*H < 0)
*H += 360;
}
COLORREF CBCGPDrawManager::HSVtoRGB (double h, double s, double v)
// Algoritm by A. R. Smith
{
int i;
double f, p, q, t;
double r, g, b;
if( s == 0 )
{
// achromatic (grey)
r = g = b = v;
}
else
{
h /= 60; // sector 0 to 5
i = (int) floor( h );
f = h - i; // factorial part of h
p = v * ( 1 - s );
q = v * ( 1 - s * f );
t = v * ( 1 - s * ( 1 - f ) );
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;
default: // case 5:
r = v;
g = p;
b = q;
break;
}
}
return RGB (
(int) (.5 + r * 255),
(int) (.5 + g * 255),
(int) (.5 + b * 255));
}
COLORREF CBCGPDrawManager::SmartMixColors (COLORREF color1, COLORREF color2,
double dblLumRatio, int k1, int k2)
{
ASSERT (k1 >= 0);
ASSERT (k2 >= 0);
if (k1 + k2 == 0)
{
ASSERT (FALSE);
return RGB (0, 0, 0);
}
COLORREF color = RGB (
(GetRValue (color1) * k1 + GetRValue (color2) * k2) / (k1 + k2),
(GetGValue (color1) * k1 + GetGValue (color2) * k2) / (k1 + k2),
(GetBValue (color1) * k1 + GetBValue (color2) * k2) / (k1 + k2));
double h1, s1, v1;
RGBtoHSV (color, &h1, &s1, &v1);
double h2, s2, v2;
RGBtoHSV (color2, &h2, &s2, &v2);
v1 = v2;
s1 = (s1 * k1 + s2 * k2) / (k1 + k2);
color = HSVtoRGB (h1, s1, v1);
if (dblLumRatio != 1.)
{
double H, S, L;
RGBtoHSL (color, &H, &S, &L);
color = HLStoRGB_ONE (H, min (1., L * dblLumRatio), S);
}
return color;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -