对于灰度图像,改变亮度只需同时增加或减少整张图像的灰度值即可,但是对于彩色图像,相对来说就比较麻烦点。对RGB空间的图像来说,需将RGB空间转换到HSL,H是色调,S是饱和度,L是亮度。改变亮度时将RGB颜色转换成HSL表示,修改L,其他不变,再将HSL转换为RGB。
公式:
RGB to HSL:
HSL to RGB:
代码实现:
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
void RGB32ChangeBright1(uint8_t* src, int width, int height, float factor)
{
int i,j;
uint32_t* img;
float r,g,b;
uint32_t color;
float h, s, l;
float m,M;
float f,d;
float tr,tg,tb;
float p,q;
float ntr,ntg,ntb;
img = (uint32_t*)src;
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
//RGB to HSL
color = *img;
r = (float)(color & 0x000000FF);
g = (float)((color >> 8) & 0x000000FF);
b = (float)((color >> 16) & 0x000000FF);
r /= 255.0;
g /= 255.0;
b /= 255.0;
m = min(min(r,g),b),
M = max(max(r,g),b);
l = (m + M)/2;
if (M==m) h = s = 0.0;
else
{
f = (r==m)?(g-b):((g==m)?(b-r):(r-g));
d = (r==m)?3.0f:((g==m)?5.0f:1.0f);
h = (d - f/(M-m));
if (h>=6.0)
h-=6;
h*=60;
s = (2*l<=1)?((M-m)/(M+m)):((M-m)/(2-M-m));
}
l += factor;
if (l < 0)
{
l = 0;
}
if (l > 1.0)
{
l = 1.0;
}
//HSL to RGB
q = 2*l<1?l*(1+s):(l+s-l*s);
p = 2*l-q;
h = h/360;
tr = h + ONE_THIRD;
tg = h;
tb = h - ONE_THIRD;
ntr = tr<0?tr+1:(tr>1?tr-1:tr);
ntg = tg<0?tg+1:(tg>1?tg-1:tg);
ntb = tb<0?tb+1:(tb>1?tb-1:tb);
r = 255*(6*ntr<1?p+(q-p)*6*ntr:(2*ntr<1?q:(3*ntr<2?p+(q-p)*6*(2.0f*ONE_THIRD-ntr):p))),
g = 255*(6*ntg<1?p+(q-p)*6*ntg:(2*ntg<1?q:(3*ntg<2?p+(q-p)*6*(2.0f*ONE_THIRD-ntg):p))),
b = 255*(6*ntb<1?p+(q-p)*6*ntb:(2*ntb<1?q:(3*ntb<2?p+(q-p)*6*(2.0f*ONE_THIRD-ntb):p)));
color &= 0xFF000000;
color = (uint8_t)(r<0?0:(r>255?255:r)) + ((uint8_t)(g<0?0:(g>255?255:g)) << 8) + ((uint8_t)(b<0?0:(b>255?255:b)) << 16);
//
*img = color;
img++;
}
}
}
测试效果:
原图:
效果图,测试参数0.2