图片羽化算法
算法思想:
(1)从边界向内亮度逐级降低直至内框同亮度
(2)四个角斜向分为两个部分处理,按就近原则,即离相邻的两个边越近就按该边相同处理方案
void ModifyBorderLight(BYTE* src, BYTE* dst, UINT width, UINT height, int d) //羽化
{
int i,v;
int m_WidthBytes = width*4;
double nMaxRatio = 2;
double r_xy=0;
for (UINT i = 0;i < height;i++)
{
for(UINT j = 0;j < width;j++)
{
//忽略非边界部分(d,d)~(height-d,width-d)
if(i>d && j>d && i<height-d && j<width-d)
continue;
//计算与边界的距离
if(i<=d)
{
if(j<=d) //左上角
r_xy = (i<j)?i:j;
else if(j>=width-d)//右上角
r_xy = width-j<i?width-j:i;
else //上边
r_xy=i;
}
else if(i>height-d)
{
if(j<=d) //左下角
r_xy = j<height-i?j:height-i;
else if(j>=width-d)//右下角
r_xy = (width-j)<(height-i)?(width-j):(height-i);
else //下边
r_xy=height-i;
}
else {
if(j<=d) //左边
r_xy=j;
else if(j>=width-d)//右边
r_xy=width-j;
}
double distance =(1 - r_xy / d);//r_xy=0 表示是区域外边框,最亮,r_xy=d 保持原亮度
if(distance<=0) continue;
for(int k=0;k<3;k++)
{
int x = dst[i*m_WidthBytes+j*4+k]* (1+distance*nMaxRatio);
if(x>255)x=255;
else if(x<0) x=0;
dst[i*m_WidthBytes+j*4+k] = x;
}
}
}
}
羽化后的效果:
以上算法可以进一步优化:
//羽化优化算法
void ModifyBorderLightC1(BYTE* src, BYTE* dst, UINT width, UINT height, int d)
{
int i,v;
int m_WidthBytes = width*4;
double nMaxRatio = 2;
double r_xy=0;
//上边
for (UINT i = 0;i <= d;i++)
{
int v_i=i*m_WidthBytes;
for(UINT j = 0;j < width;j++)
{
if(j<=d) //左上角
r_xy = (i<j)?i:j;
else if(j>=width-d)//右上角
r_xy = width-j<i?width-j:i;
else //上边
r_xy=i;
double distance =1+(1 - r_xy / d)*nMaxRatio;
if(distance<=0) continue;
int v_j=v_i+j*4;
for(int k=0;k<3;k++)
{
int x = dst[v_j+k]* distance;
if(x>255)x=255;
else if(x<0) x=0;
dst[v_j+k] = x;
}
}
}
//下边
for (UINT i = height-d;i < height;i++)
{
int v_i=i*m_WidthBytes;
for(UINT j = 0;j < width;j++)
{
if(j<=d) //左下角
r_xy = j<height-i?j:height-i;
else if(j>=width-d)//右下角
r_xy = (width-j)<(height-i)?(width-j):(height-i);
else //下边
r_xy=height-i;
double distance =1+(1 - r_xy / d)*nMaxRatio;
if(distance<=0) continue;
int v_j=v_i+j*4;
for(int k=0;k<3;k++)
{
int x = dst[v_j+k]* distance;
if(x>255)x=255;
else if(x<0) x=0;
dst[v_j+k] = x;
}
}
}
//左边
for (UINT i = d+1;i < height-d;i++)
{
int v_i=i*m_WidthBytes;
for(UINT j = 0;j < d;j++)
{
r_xy=j;
double distance =1+(1 - r_xy / d)*nMaxRatio;
if(distance<=0) continue;
int v_j=v_i+j*4;
for(int k=0;k<3;k++)
{
int x = dst[v_j+k]* distance;
if(x>255)x=255;
else if(x<0) x=0;
dst[v_j+k] = x;
}
}
}
//右边
for (UINT i = d+1;i < height-d;i++)
{
int v_i=i*m_WidthBytes;
for(UINT j = width-d;j < width;j++)
{
r_xy=width-j;
double distance =1+(1 - r_xy / d)*nMaxRatio;
if(distance<=0) continue;
int v_j=v_i+j*4;
for(int k=0;k<3;k++)
{
int x = dst[v_j+k]* distance;
if(x>255)x=255;
else if(x<0) x=0;
dst[v_j+k] = x;
}
}
}
}
考虑到对称,算法可以再次优化:
//羽化优化算法
void ModifyBorderLightC1(BYTE* src, BYTE* dst, UINT width, UINT height, int d)
{
int i,v;
int m_WidthBytes = width*4;
double nMaxRatio = 2;
double r_xy=0;
//上边和下边
for (UINT i = 0;i <= d;i++)
{
int v_i_top = i*m_WidthBytes;
int v_i_bottom = (height-i-1)*m_WidthBytes;
for(UINT j = 0;j < width;j++)
{
if(j<d) //左上角
r_xy = (i<j)?i:j;
else if(j>=width-d)//右上角
r_xy = width-j<i?width-j:i;
else //上边
r_xy=i;
double distance =1+(1 - r_xy / d)*nMaxRatio;
if(distance<=0) continue;
int v_j_top =v_i_top+j*4;
int v_j_bottom =v_i_bottom+j*4;
for(int k=0;k<3;k++)
{
int x = dst[v_j_top+k]* distance;
if(x>255)x=255;
else if(x<0) x=0;
dst[v_j_top+k] = x;
x = dst[v_j_bottom+k]* distance;
if(x>255)x=255;
else if(x<0) x=0;
dst[v_j_bottom+k] = x;
}
}
}
//左边和右边
for (UINT i = d+1;i < height-d-1;i++)
{
int v_i=i*m_WidthBytes;
for(UINT j = 0;j < d;j++)
{
r_xy=j;
double distance =1+(1 - r_xy / d)*nMaxRatio;
if(distance<=0) continue;
int v_j_left = v_i+j*4;
int v_j_right = v_i+(width-j-1)*4;
for(int k=0;k<3;k++)
{
int x = dst[v_j_left+k]* distance;
if(x>255)x=255;
else if(x<0) x=0;
dst[v_j_left+k] = x;
x = dst[v_j_right+k]* distance;
if(x>255)x=255;
else if(x<0) x=0;
dst[v_j_right+k] = x;
}
}
}
}