图片羽化算法

图片羽化算法

算法思想:

(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;
			}
		}
	}	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丁亚涛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值