利用AlphaBlend实现高斯模糊

原文:http://simplesource.blog.163.com/blog/static/1034140620113284223430/

       高斯模糊就是把一个点与其周围的点进行相加然后平均,但是图像中的每个点都需要进行计算,所以计算量比较大,而且取像素设置像素的代码写起来也比较繁琐。今天我突然想到AlphaBlend其实就是整幅图像的像素与像素的相加操作,那么是不是可以用若干次AlphaBlend来实现高斯模糊呢?于是尝试了一下,果然可以。

  代码如下:

 bool Blur(HBITMAP hBmp, double a = 1, double b = 0.08)

{

    static int modles[][3] =

    {

        {1,   0,  0},

        {0,   1,  0},

        {-1,  0,  0},

        {0,  -1,  0},

        {1,   1,  0},

        {1,  -1,  0},

        {-1,  1,  0},

        {-1, -1,  0}

    };

    int i;

    for(i = 7; i >= 0; i--)

    {

        modles[i][2] = (int)(255 * b);

        b = b / (1 - b);

        if(i == 4)

        {

            b *= 1.4142135623;

        }

    }

    CWindowDC wdc(NULL);

    CDC dc;

    dc.CreateCompatibleDC(&wdc);

    CImage imgSrc;

    imgSrc.Attach(hBmp);

    CBitmap bmp;

    if(bmp.CreateCompatibleBitmap(&wdc, imgSrc.GetWidth(), imgSrc.GetHeight()))

    {

        dc.SelectObject(&bmp);

        int alpha = (int)(a * 255);

        if(alpha > 254)

        {

            imgSrc.BitBlt(dc, 0, 0);

        }

        else if(alpha > 1)

        {

            imgSrc.AlphaBlend(dc, 0, 0, alpha);

        }

        for(i = 0; i < 8; i++)

        {

            imgSrc.AlphaBlend(dc, modles[i][0], modles[i][1], modles[i][2]);

        }

        imgSrc.Detach();

        dc.SelectObject(hBmp);

        imgSrc.Attach(bmp);

        imgSrc.BitBlt(dc, 0, 0);

        imgSrc.Detach();

        return true;

    }

    imgSrc.Detach();

    return false;

}

  至于标红色的那段,其实是因为每次AlphaBlend都是一次像素叠加运算,如果每次都是用相同的半透明度那么会导致最后一次的叠加占的比重最大,这样模糊就会发生偏移,而与正常的高斯模糊出现出入。

  实际上每次AlphaBlend的像素叠加中每个像素的公式可以用下面的公式表示:

 c = c0 * a + c1 * (1 - a) 

a表示半透明度,c0表示原始像素0,c1表示原始像素1,c表示叠加后的新像素

  这样经过8次AlphaBlend叠加后新像素的计算公式如下

 c = (1 - a8)(1 - a7)...(1 - a1) * c0 + (1 - a8)(1 - a7)...(1 - a2)* a1* c1 + (1 - a8)(1 - a7)...(1 - a3) * a2 * c2 + ... + a8 * c8 

注意:这里有9个项

  我们的目标是c0到c8在c中的占比为定值(比如1:1:1:1:1:1:1:1)那么就有如下方程

 a8 = a;

(1 - a8) * a7 = a;

(1 - a8) * (1 - a7) * a6 = a;

...

(1 - a8)(1 - a7)...(1 - a2)*a1 = a;

注意:我们只要8个方程。这里的a表示每个像素的目标占比,a1到a8表示每次AlphaBlend的透明度

  简化后可以得到

 a8 = a;

a7 = a / (1 - a8) = a8 / (1 - a8);

a6 = a / (1 - a8) / (1 - a7) = a7 / (1 - a7);

...

a1 = a2 / (1 - a2);

  因此可以得到标红色的那段计算每次AlphaBlend的透明度的代码。至于其中的1.414213623其实是根号2,我假设对角线上的点占比要比上下左右的点少一些。

  程序截图:

利用AlphaBlend实现高斯模糊 - 简单代码 - 简单代码

 源代码下载:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值