下载了vs2010,今天终于可以初步体验了。看好的高级调试功能IntelliTrace功能没能符合我的预期,居然不支持局部变量,这样这个功能似乎就显得鸡肋了。随便写点什么体验下,就决定实现了这个类似QQ换肤自动改变图片颜色的效果。
其实原理很简单,就是将RGB颜色转换成HSL,而HSL就可以方便的实现QQ的改变图片颜色的效果了。HSL就是用色调(Hue)、饱和度(Saturation)、亮度(Lightness)。更加接近与人眼。通过调整色调就可以做到方便的改变图片的颜色。
将图片的每个像素的RGB取出,转换成HSL,然后根据变化的HSL值计算出新的HSL,再转成RGB放回去,主要代码如下:
void RGBtoHSL(BYTE R,BYTE G,BYTE B,float* H,float* S,float* L)
{
BYTE minval = min(R,min(G,B));
BYTE maxval = max(R,max(G,B));
float mdiff = float(maxval) - float(minval);
float msum = float(maxval) + float(minval);
*L = msum / 510.0f;
if (maxval == minval)
{
*S = 0.0f;
*H = 0.0f;
}
else
{
float rnorm = (maxval - R) / mdiff;
float gnorm = (maxval - G) / mdiff;
float bnorm = (maxval - B) / mdiff;
*S = (*L <= 0.5f) ? (mdiff / msum) : (mdiff / (510.0f - msum));
if(R == maxval)
*H = 60.0f * (6.0f + bnorm - gnorm);
if(G == maxval)
*H = 60.0f * (2.0f + rnorm - bnorm);
if(B == maxval)
*H = 60.0f * (4.0f + gnorm - rnorm);
if (*H > 360.0f)
*H -= 360.0f;
}
}
BYTE HueToRGB(float rm1,float rm2,float rh)
{
while(rh > 360.0f)
rh -= 360.0f;
while(rh < 0.0f)
rh += 360.f;
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;
float n = rm1*255;
int m = min((int)n,255);
m = max(0,m);
return (BYTE)m;//(rm1 * 255);
}
COLORREF HSLtoRGB(float H,float S,float L)
{
BYTE r,g,b;
L = min(1,L);
S = min(1,S);
if(S == 0.0)
{
r = g = b = (BYTE)(255 * L);
}
else
{
float rm1, rm2;
if (L <= 0.5f)
rm2 = L + L * S;
else
rm2 = L + S - L * S;
rm1 = 2.0f * L - rm2;
r = HueToRGB(rm1, rm2, H + 120.0f);
g = HueToRGB(rm1, rm2, H);
b = HueToRGB(rm1, rm2, H - 120.0f);
}
return RGB(r,g,b);
}
BOOL CHSLDlg::AdjustHSL(Bitmap* pBmp, int degHue, int perSaturation, int perLuminosity)
{
if (!pBmp)
{
ASSERT(FALSE);
return FALSE;
}
if(perSaturation < 0 || perLuminosity < 0)
return FALSE;
if(degHue == 0 && perSaturation == 100 && perLuminosity == 100)
return TRUE; //未作调整,直接返回
UINT nWidth = m_pBmpBK->GetWidth();
UINT nHeight = m_pBmpBK->GetHeight();
Color cr = 0;
float H, S, L = 0;
for (UINT i = 0; i < nWidth; ++i)
{
for (UINT j = 0; j < nHeight; ++j)
{
m_pBmpBK->GetPixel(i, j, &cr);
RGBtoHSL(cr.GetRed(), cr.GetGreen(), cr.GetBlue(), &H, &S, &L);
H += degHue;
S = (S*perSaturation/100.0f);
L = (L*perLuminosity/100.0f);
cr.SetFromCOLORREF(HSLtoRGB(H,S,L));
m_pBmpBK->SetPixel(i, j, cr);
}
}
return TRUE;
}
http://longjing_g.download.csdn.net/