注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

简单代码

寻找代码的灵魂

 
 
 

日志

 
 
关于我

对于本博客内所有原创文章和代码的引用必须标明“来源:http://simplesource.blog.163.com/”。如需应用于商业目的必须经本人同意,本人对所有原创文章和代码保留一切权利。 PS:需要部分程序源代码的请留下邮箱地址

网易考拉推荐

利用AlphaBlend实现高斯模糊  

2011-04-02 21:38:22|  分类: 我的程序 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

  高斯模糊就是把一个点与其周围的点进行相加然后平均,但是图像中的每个点都需要进行计算,所以计算量比较大,而且取像素设置像素的代码写起来也比较繁琐。今天我突然想到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
   

  评论这张
 
阅读(2104)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017