在hge中实现对静态图片的动态模糊 (box blur版)

在hge中实现对静态图片的动态模糊 (box blur版)


http://blog.csdn.net/jia20003/article/details/7201069

在该前辈的博客处找了段java的均值模糊(box blur)的代码,我把它换成hge的了,效率还可以,不过应该比不上前一篇的方法。但box blur是比较正统的模糊算法,不像前一篇的那般“邪道”,他直接处理像素,其思想方法类似高斯算法,实现上又比高斯算法要简单,虽然效果上比高斯差,但也值得了。

这里我简单讲一下均值模糊的步骤,当然各位也可以看那位前辈的博客:)

1.输入一个半径r,定义模糊的方向,r越大,则越模糊(虽然说是半径r,但是模糊的方向只取一条线,或两条线,例如横,竖,横与竖)。

2.根据1建立一个索引,其实就是空间换时间,提前算好了r范围内所有可能出现的颜色数值之和的均值,这是个固定的值,所以可以一开始就建)。

3.计算第一个r区域的各个像素值之和(r,g,b,a分别算)

4.开始遍历想要输出的纹理像素(注意原纹理矩阵依然保留),每行第一个像素,直接给他赋予2中的均值,往后每遍历一个像素,3计算的像素值之和都加上x+r +1和 x - r 之间的差(或者是y+r+1和y-r-1的差),然后再次赋予新的均值。

代码(使用横方向模糊,每摁一下L键开始模糊,半径为10):


/*
**
** motion blur demo
** based off of tutorial4..
*/
 
 
#include 
" ..\..\include\hge.h "
#include 
" ..\..\include\hgesprite.h "
 
 
HGE 
* hge = 0 ;
 
 
hgeSprite
*  spt1;

float  x = 0.0f , y = 0.0f ;


HTEXTURE boxblur( HTEXTURE 
in int  radius ) ;

bool  FrameFunc()
{
    
if (hge -> Input_KeyDown(HGEK_L))
    {
        HTEXTURE dumptex 
=  spt1 -> GetTexture();
        HTEXTURE tex2 
=  boxblur(dumptex, 10 );
        spt1
-> SetTexture(tex2);
        hge
-> Texture_Free(dumptex);
    }

    hge
-> Gfx_BeginScene();
    hge
-> Gfx_Clear( 0 );
 
    spt1
-> Render(x, y);

    hge
-> Gfx_EndScene();

    
return   false ;
}
 

int  WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR,  int )
{
    hge 
=  hgeCreate(HGE_VERSION);

    hge
-> System_SetState(HGE_FRAMEFUNC, FrameFunc);
    hge
-> System_SetState(HGE_TITLE,  " HGE RealTime Blur Demo " );
    hge
-> System_SetState(HGE_FPS,  100 );
    hge
-> System_SetState(HGE_WINDOWED,  true );
    hge
-> System_SetState(HGE_SCREENWIDTH,  1024 );
    hge
-> System_SetState(HGE_SCREENHEIGHT,  768 );
    hge
-> System_SetState(HGE_SCREENBPP,  32 );
 
    
if (hge -> System_Initiate()) {
        
        HTEXTURE tex
= hge -> Texture_Load( " alley_normal.jpg " );
        
if ( ! tex)
        {
            MessageBox(NULL, 
" Can't load the picture file " " Error " , MB_OK  |  MB_ICONERROR  |  MB_SYSTEMMODAL);
            hge
-> System_Shutdown();
            hge
-> Release();
            
return   0 ;
        }
 
        spt1
= new  hgeSprite(tex,  0 0 1024 768 ); // 这是最后会显示的精灵
               
        hge
-> System_Start();

        hge
-> Texture_Free(spt1 -> GetTexture());

        delete spt1;
    }
 
    
//  Clean up and shutdown
    hge -> System_Shutdown();
    hge
-> Release();
    
return   0 ;
}

HTEXTURE boxblur( HTEXTURE 
in int  radius ) 
{  
    
int  width, height;
    width 
=  hge -> Texture_GetWidth( in );
    height 
=  hge -> Texture_GetHeight( in );
    HTEXTURE 
out   =  hge -> Texture_Create(width, height);

    
int  widthMinus1  =  width - 1 ;  
    
int  tableSize  =   2 * radius + 1 ;  
    unsigned 
int *  divide  =   new unsigned int [ 256 * tableSize];  

    
//  the value scope will be 0 to 255, and number of 0 is table size  
    
//  will get means from index not calculate result again since   
    
//  color value must be  between 0 and 255.  
     for  (  int  i  =   0 ; i  <   256 * tableSize; i ++  )  
        divide[i] 
=  i / tableSize;   

    
int  inIndex  =   0 ;  

    unsigned 
int *  in_   =  (unsigned  int * )hge -> Texture_Lock( in );
    unsigned 
int *  out_  =  (unsigned  int * )hge -> Texture_Lock( out false );

    
//    
     for  (  int  y  =   0 ; y  <  height; y ++  ) {  
        
int  outIndex  =  y;  
        unsigned 
int  ta  =   0 , tr  =   0 , tg  =   0 , tb  =   0 //  ARGB -> prepare for the alpha, red, green, blue color value.  

        
for  (  int  i  =   - radius; i  <=  radius; i ++  ) 
        {  
            
int  clamp  =  (i  <   0 ?   0  : (i  >  (width - 1 ))  ?  (width - 1 ) : i;
            unsigned 
int  rgb  =  in_[inIndex  +  clamp];  //  read input pixel data here. table size data.  
            ta  +=  (rgb  >>   24 &   0xff ;  
            tr 
+=  (rgb  >>   16 &   0xff ;  
            tg 
+=  (rgb  >>   8 &   0xff ;  
            tb 
+=  rgb  &   0xff ;  
        }  

        
for  (  int  x  =   0 ; x  <  width; x ++  ) 
        { 
//  get output pixel data.  
            out_[ outIndex * width  +  x ]  =  (divide[ta]  <<   24 |  (divide[tr]  <<   16 |  (divide[tg]  <<   8 |  divide[tb];  //  calculate the output data.  

            
int  i1  =  x + radius + 1 ;  
            
if  ( i1  >  widthMinus1 )  
                i1 
=  widthMinus1;  
            
int  i2  =  x - radius;  
            
if  ( i2  <   0  )  
                i2 
=   0 ;  
            
int  rgb1  =  in_[inIndex + i1];  
            
int  rgb2  =  in_[inIndex + i2];  

            ta 
+=  ((rgb1  >>   24 &   0xff ) - ((rgb2  >>   24 &   0xff );  
            tr 
+=  ((rgb1  &   0xff0000 ) - (rgb2  &   0xff0000 ))  >>   16 ;  
            tg 
+=  ((rgb1  &   0xff00 ) - (rgb2  &   0xff00 ))  >>   8 ;  
            tb 
+=  (rgb1  &   0xff ) - (rgb2  &   0xff );
        }  
        inIndex 
+=  width;  //  next (i+ column number * n, n=1.n-1)  
    } 

    hge
-> Texture_Unlock( in );
    hge
-> Texture_Unlock( out );
    delete [] divide;
    
return   out ;
}



你可能感兴趣的:(在hge中实现对静态图片的动态模糊 (box blur版))