图片HSL颜色调节(仿QQ换肤)

下载了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;

}

源码下载:
上传了之后,总是看不到,csdn的更新实在太慢,好在我上传的资源不多,有需要的自己找吧,呵呵

 

http://longjing_g.download.csdn.net/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值