# 高斯模糊
  - 高斯模糊就是将指定像素变换为其与周边像素加权平均后的值,权重就是高斯分布函数计算出来的值。

一种实现

      [点击打开链接](http://my.oschina.net/tonywolf/blog/64896)<-这里是一片关于高斯模糊算法的介绍,我们需要首先根据高斯分布函数计算权重值,为了提高效率我们采用一维高斯分布函数,然后处理图像的时候在横向和纵向进行两次计算得到结果。下面是一种实现
    

    
    <div class="dp-highlighter bg_java">
      <div class="bar">
        <div class="tools">
          

            **[java]** [view plain](http://blog.csdn.net/xu_fu/article/details/23131241#)[copy](http://blog.csdn.net/xu_fu/article/details/23131241#)[print](http://blog.csdn.net/xu_fu/article/details/23131241#)[?](http://blog.csdn.net/xu_fu/article/details/23131241#)
          

          
          <div>
            <embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="29" height="15" align="middle" name="ZeroClipboardMovie_1">
            </embed>
          </div>
        </div>
      </div>
      
      
        - <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> gaussBlur(<span class="keyword">int</span>[] data, <span class="keyword">int</span> width, <span class="keyword">int</span> height, <span class="keyword">int</span> radius,
        
        - <span class="keyword">float</span> sigma) {
        
        - 
        - <span class="keyword">float</span> pa = (<span class="keyword">float</span>) (<span class="number">1</span> / (Math.sqrt(<span class="number">2</span> * Math.PI) * sigma));
        
        - <span class="keyword">float</span> pb = &#8211;<span class="number">1</span>.0f / (<span class="number">2</span> * sigma * sigma);
        
        - 
        - <span class="comment">// generate the Gauss Matrix</span>
        
        - <span class="keyword">float</span>[] gaussMatrix = <span class="keyword">new</span> <span class="keyword">float</span>[radius * <span class="number">2</span> + <span class="number">1</span>];
        
        - <span class="keyword">float</span> gaussSum = 0f;
        
        - <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number"></span>, x = -radius; x <= radius; ++x, ++i) {
        
        - <span class="keyword">float</span> g = (<span class="keyword">float</span>) (pa * Math.exp(pb * x * x));
        
        - gaussMatrix[i] = g;
        
        - gaussSum += g;
        
        - }
        
        - 
        - <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number"></span>, length = gaussMatrix.length; i < length; ++i) {
        
        - gaussMatrix[i] /= gaussSum;
        
        - }
        
        - 
        - <span class="comment">// x direction</span>
        
        - <span class="keyword">for</span> (<span class="keyword">int</span> y = <span class="number"></span>; y < height; ++y) {
        
        - <span class="keyword">for</span> (<span class="keyword">int</span> x = <span class="number"></span>; x < width; ++x) {
        
        - <span class="keyword">float</span> r = <span class="number"></span>, g = <span class="number"></span>, b = <span class="number"></span>;
        
        - gaussSum = <span class="number"></span>;
        
        - <span class="keyword">for</span> (<span class="keyword">int</span> j = -radius; j <= radius; ++j) {
        
        - <span class="keyword">int</span> k = x + j;
        
        - <span class="keyword">if</span> (k >= <span class="number"></span> && k < width) {
        
        - <span class="keyword">int</span> index = y * width + k;
        
        - <span class="keyword">int</span> color = data[index];
        
        - <span class="keyword">int</span> cr = (color & <span class="number">0x00ff0000</span>) >> <span class="number">16</span>;
        
        - <span class="keyword">int</span> cg = (color & <span class="number">0x0000ff00</span>) >> <span class="number">8</span>;
        
        - <span class="keyword">int</span> cb = (color & <span class="number">0x000000ff</span>);
        
        - 
        - r += cr * gaussMatrix[j + radius];
        
        - g += cg * gaussMatrix[j + radius];
        
        - b += cb * gaussMatrix[j + radius];
        
        - 
        - gaussSum += gaussMatrix[j + radius];
        
        - }
        
        - }
        
        - 
        - <span class="keyword">int</span> index = y * width + x;
        
        - <span class="keyword">int</span> cr = (<span class="keyword">int</span>) (r / gaussSum);
        
        - <span class="keyword">int</span> cg = (<span class="keyword">int</span>) (g / gaussSum);
        
        - <span class="keyword">int</span> cb = (<span class="keyword">int</span>) (b / gaussSum);
        
        - 
        - data[index] = cr << <span class="number">16</span> | cg << <span class="number">8</span> | cb | <span class="number">0xff000000</span>;
        
        - }
        
        - }
        
        - 
        - <span class="comment">// y direction</span>
        
        - <span class="keyword">for</span> (<span class="keyword">int</span> x = <span class="number"></span>; x < width; ++x) {
        
        - <span class="keyword">for</span> (<span class="keyword">int</span> y = <span class="number"></span>; y < height; ++y) {
        
        - <span class="keyword">float</span> r = <span class="number"></span>, g = <span class="number"></span>, b = <span class="number"></span>;
        
        - gaussSum = <span class="number"></span>;
        
        - <span class="keyword">for</span> (<span class="keyword">int</span> j = -radius; j <= radius; ++j) {
        
        - <span class="keyword">int</span> k = y + j;
        
        - <span class="keyword">if</span> (k >= <span class="number"></span> && k < height) {
        
        - <span class="keyword">int</span> index = k * width + x;
        
        - <span class="keyword">int</span> color = data[index];
        
        - <span class="keyword">int</span> cr = (color & <span class="number">0x00ff0000</span>) >> <span class="number">16</span>;
        
        - <span class="keyword">int</span> cg = (color & <span class="number">0x0000ff00</span>) >> <span class="number">8</span>;
        
        - <span class="keyword">int</span> cb = (color & <span class="number">0x000000ff</span>);
        
        - 
        - r += cr * gaussMatrix[j + radius];
        
        - g += cg * gaussMatrix[j + radius];
        
        - b += cb * gaussMatrix[j + radius];
        
        - 
        - gaussSum += gaussMatrix[j + radius];
        
        - }
        
        - }
        
        - 
        - <span class="keyword">int</span> index = y * width + x;
        
        - <span class="keyword">int</span> cr = (<span class="keyword">int</span>) (r / gaussSum);
        
        - <span class="keyword">int</span> cg = (<span class="keyword">int</span>) (g / gaussSum);
        
        - <span class="keyword">int</span> cb = (<span class="keyword">int</span>) (b / gaussSum);
        
        - data[index] = cr << <span class="number">16</span> | cg << <span class="number">8</span> | cb | <span class="number">0xff000000</span>;
        
        - }
        
        - }
        
        - }
        
      
    </div>
    
    

      实际测试会发现这种计算方式是很耗时间的,而且模糊半径越大,从原理也可以看到计算量是平方增长的,所以计算时间也越长。
    

    
    ## <a name="t2"></a>RenderScript
    
    

      RenderScript是Android在API 11之后加入的,用于高效的图片处理,包括模糊、混合、矩阵卷积计算等,代码示例如下
    

    
    <div class="dp-highlighter bg_java">
      <div class="bar">
        <div class="tools">
          

            **[java]** [view plain](http://blog.csdn.net/xu_fu/article/details/23131241#)[copy](http://blog.csdn.net/xu_fu/article/details/23131241#)[print](http://blog.csdn.net/xu_fu/article/details/23131241#)[?](http://blog.csdn.net/xu_fu/article/details/23131241#)
          

          
          <div>
            <embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="29" height="15" align="middle" name="ZeroClipboardMovie_2">
            </embed>
          </div>
        </div>
      </div>
      
      
        - <span class="keyword">public</span> Bitmap blurBitmap(Bitmap bitmap){
        
        - 
        - <span class="comment">//Let&#8217;s create an empty bitmap with the same size of the bitmap we want to blur</span>
        
        - Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
        
        - 
        - <span class="comment">//Instantiate a new Renderscript</span>
        
        - RenderScript rs = RenderScript.create(getApplicationContext());
        
        - 
        - <span class="comment">//Create an Intrinsic Blur Script using the Renderscript</span>
        
        - ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        
        - 
        - <span class="comment">//Create the Allocations (in/out) with the Renderscript and the in/out bitmaps</span>
        
        - Allocation allIn = Allocation.createFromBitmap(rs, bitmap);
        
        - Allocation allOut = Allocation.createFromBitmap(rs, outBitmap);
        
        - 
        - <span class="comment">//Set the radius of the blur</span>
        
        - blurScript.setRadius(<span class="number">25</span>.f);
        
        - 
        - <span class="comment">//Perform the Renderscript</span>
        
        - blurScript.setInput(allIn);
        
        - blurScript.forEach(allOut);
        
        - 
        - <span class="comment">//Copy the final bitmap created by the out Allocation to the outBitmap</span>
        
        - allOut.copyTo(outBitmap);
        
        - 
        - <span class="comment">//recycle the original bitmap</span>
        
        - bitmap.recycle();
        
        - 
        - <span class="comment">//After finishing everything, we destroy the Renderscript.</span>
        
        - rs.destroy();
        
        - 
        - <span class="keyword">return</span> outBitmap;
        
        - 
        - 
        - }
        
      
    </div>
    
    

      (示例来源 [https://gist.github.com/Mariuxtheone/903c35b4927c0df18cf8](https://gist.github.com/Mariuxtheone/903c35b4927c0df18cf8))
    

    
    ## <a name="t3"></a>FastBlur
    
    <div>
      <div class="dp-highlighter bg_java">
        <div class="bar">
          <div class="tools">
            

              **[java]** [view plain](http://blog.csdn.net/xu_fu/article/details/23131241#)[copy](http://blog.csdn.net/xu_fu/article/details/23131241#)[print](http://blog.csdn.net/xu_fu/article/details/23131241#)[?](http://blog.csdn.net/xu_fu/article/details/23131241#)
            

            
            <div>
              <embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="29" height="15" align="middle" name="ZeroClipboardMovie_3">
              </embed>
            </div>
          </div>
        </div>
        
        
          - <span class="keyword">public</span> <span class="keyword">class</span> FastBlur {
          
          - 
          - <span class="keyword">public</span> <span class="keyword">static</span> Bitmap doBlur(Bitmap sentBitmap, <span class="keyword">int</span> radius, <span class="keyword">boolean</span> canReuseInBitmap) {
          
          - 
          - <span class="comment">// Stack Blur v1.0 from</span>
          
          - <span class="comment">// http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html</span>
          
          - <span class="comment">//</span>
          
          - <span class="comment">// Java Author: Mario Klingemann <mario at quasimondo.com></span>
          
          - <span class="comment">// http://incubator.quasimondo.com</span>
          
          - <span class="comment">// created Feburary 29, 2004</span>
          
          - <span class="comment">// Android port : Yahel Bouaziz <yahel at kayenko.com></span>
          
          - <span class="comment">// http://www.kayenko.com</span>
          
          - <span class="comment">// ported april 5th, 2012</span>
          
          - 
          - <span class="comment">// This is a compromise between Gaussian Blur and Box blur</span>
          
          - <span class="comment">// It creates much better looking blurs than Box Blur, but is</span>
          
          - <span class="comment">// 7x faster than my Gaussian Blur implementation.</span>
          
          - <span class="comment">//</span>
          
          - <span class="comment">// I called it Stack Blur because this describes best how this</span>
          
          - <span class="comment">// filter works internally: it creates a kind of moving stack</span>
          
          - <span class="comment">// of colors whilst scanning through the image. Thereby it</span>
          
          - <span class="comment">// just has to add one new block of color to the right side</span>
          
          - <span class="comment">// of the stack and remove the leftmost color. The remaining</span>
          
          - <span class="comment">// colors on the topmost layer of the stack are either added on</span>
          
          - <span class="comment">// or reduced by one, depending on if they are on the right or</span>
          
          - <span class="comment">// on the left side of the stack.</span>
          
          - <span class="comment">//</span>
          
          - <span class="comment">// If you are using this algorithm in your code please add</span>
          
          - <span class="comment">// the following line:</span>
          
          - <span class="comment">//</span>
          
          - <span class="comment">// Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com></span>
          
          - 
          - Bitmap bitmap;
          
          - <span class="keyword">if</span> (canReuseInBitmap) {
          
          - bitmap = sentBitmap;
          
          - } <span class="keyword">else</span> {
          
          - bitmap = sentBitmap.copy(sentBitmap.getConfig(), <span class="keyword">true</span>);
          
          - }
          
          - 
          - <span class="keyword">if</span> (radius < <span class="number">1</span>) {
          
          - <span class="keyword">return</span> (<span class="keyword">null</span>);
          
          - }
          
          - 
          - <span class="keyword">int</span> w = bitmap.getWidth();
          
          - <span class="keyword">int</span> h = bitmap.getHeight();
          
          - 
          - <span class="keyword">int</span>[] pix = <span class="keyword">new</span> <span class="keyword">int</span>[w * h];
          
          - bitmap.getPixels(pix, <span class="number"></span>, w, <span class="number"></span>, <span class="number"></span>, w, h);
          
          - 
          - <span class="keyword">int</span> wm = w &#8211; <span class="number">1</span>;
          
          - <span class="keyword">int</span> hm = h &#8211; <span class="number">1</span>;
          
          - <span class="keyword">int</span> wh = w * h;
          
          - <span class="keyword">int</span> div = radius + radius + <span class="number">1</span>;
          
          - 
          - <span class="keyword">int</span> r[] = <span class="keyword">new</span> <span class="keyword">int</span>[wh];
          
          - <span class="keyword">int</span> g[] = <span class="keyword">new</span> <span class="keyword">int</span>[wh];
          
          - <span class="keyword">int</span> b[] = <span class="keyword">new</span> <span class="keyword">int</span>[wh];
          
          - <span class="keyword">int</span> rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
          
          - <span class="keyword">int</span> vmin[] = <span class="keyword">new</span> <span class="keyword">int</span>[Math.max(w, h)];
          
          - 
          - <span class="keyword">int</span> divsum = (div + <span class="number">1</span>) >> <span class="number">1</span>;
          
          - divsum *= divsum;
          
          - <span class="keyword">int</span> dv[] = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">256</span> * divsum];
          
          - <span class="keyword">for</span> (i = <span class="number"></span>; i < <span class="number">256</span> * divsum; i++) {
          
          - dv[i] = (i / divsum);
          
          - }
          
          - 
          - yw = yi = <span class="number"></span>;
          
          - 
          - <span class="keyword">int</span>[][] stack = <span class="keyword">new</span> <span class="keyword">int</span>[div][<span class="number">3</span>];
          
          - <span class="keyword">int</span> stackpointer;
          
          - <span class="keyword">int</span> stackstart;
          
          - <span class="keyword">int</span>[] sir;
          
          - <span class="keyword">int</span> rbs;
          
          - <span class="keyword">int</span> r1 = radius + <span class="number">1</span>;
          
          - <span class="keyword">int</span> routsum, goutsum, boutsum;
          
          - <span class="keyword">int</span> rinsum, ginsum, binsum;
          
          - 
          - <span class="keyword">for</span> (y = <span class="number"></span>; y < h; y++) {
          
          - rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = <span class="number"></span>;
          
          - <span class="keyword">for</span> (i = -radius; i <= radius; i++) {
          
          - p = pix[yi + Math.min(wm, Math.max(i, <span class="number"></span>))];
          
          - sir = stack[i + radius];
          
          - sir[<span class="number"></span>] = (p & <span class="number">0xff0000</span>) >> <span class="number">16</span>;
          
          - sir[<span class="number">1</span>] = (p & <span class="number">0x00ff00</span>) >> <span class="number">8</span>;
          
          - sir[<span class="number">2</span>] = (p & <span class="number">0x0000ff</span>);
          
          - rbs = r1 &#8211; Math.abs(i);
          
          - rsum += sir[<span class="number"></span>] * rbs;
          
          - gsum += sir[<span class="number">1</span>] * rbs;
          
          - bsum += sir[<span class="number">2</span>] * rbs;
          
          - <span class="keyword">if</span> (i > <span class="number"></span>) {
          
          - rinsum += sir[<span class="number"></span>];
          
          - ginsum += sir[<span class="number">1</span>];
          
          - binsum += sir[<span class="number">2</span>];
          
          - } <span class="keyword">else</span> {
          
          - routsum += sir[<span class="number"></span>];
          
          - goutsum += sir[<span class="number">1</span>];
          
          - boutsum += sir[<span class="number">2</span>];
          
          - }
          
          - }
          
          - stackpointer = radius;
          
          - 
          - <span class="keyword">for</span> (x = <span class="number"></span>; x < w; x++) {
          
          - 
          - r[yi] = dv[rsum];
          
          - g[yi] = dv[gsum];
          
          - b[yi] = dv[bsum];
          
          - 
          - rsum -= routsum;
          
          - gsum -= goutsum;
          
          - bsum -= boutsum;
          
          - 
          - stackstart = stackpointer &#8211; radius + div;
          
          - sir = stack[stackstart % div];
          
          - 
          - routsum -= sir[<span class="number"></span>];
          
          - goutsum -= sir[<span class="number">1</span>];
          
          - boutsum -= sir[<span class="number">2</span>];
          
          - 
          - <span class="keyword">if</span> (y == <span class="number"></span>) {
          
          - vmin[x] = Math.min(x + radius + <span class="number">1</span>, wm);
          
          - }
          
          - p = pix[yw + vmin[x]];
          
          - 
          - sir[<span class="number"></span>] = (p & <span class="number">0xff0000</span>) >> <span class="number">16</span>;
          
          - sir[<span class="number">1</span>] = (p & <span class="number">0x00ff00</span>) >> <span class="number">8</span>;
          
          - sir[<span class="number">2</span>] = (p & <span class="number">0x0000ff</span>);
          
          - 
          - rinsum += sir[<span class="number"></span>];
          
          - ginsum += sir[<span class="number">1</span>];
          
          - binsum += sir[<span class="number">2</span>];
          
          - 
          - rsum += rinsum;
          
          - gsum += ginsum;
          
          - bsum += binsum;
          
          - 
          - stackpointer = (stackpointer + <span class="number">1</span>) % div;
          
          - sir = stack[(stackpointer) % div];
          
          - 
          - routsum += sir[<span class="number"></span>];
          
          - goutsum += sir[<span class="number">1</span>];
          
          - boutsum += sir[<span class="number">2</span>];
          
          - 
          - rinsum -= sir[<span class="number"></span>];
          
          - ginsum -= sir[<span class="number">1</span>];
          
          - binsum -= sir[<span class="number">2</span>];
          
          - 
          - yi++;
          
          - }
          
          - yw += w;
          
          - }
          
          - <span class="keyword">for</span> (x = <span class="number"></span>; x < w; x++) {
          
          - rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = <span class="number"></span>;
          
          - yp = -radius * w;
          
          - <span class="keyword">for</span> (i = -radius; i <= radius; i++) {
          
          - yi = Math.max(<span class="number"></span>, yp) + x;
          
          - 
          - sir = stack[i + radius];
          
          - 
          - sir[<span class="number"></span>] = r[yi];
          
          - sir[<span class="number">1</span>] = g[yi];
          
          - sir[<span class="number">2</span>] = b[yi];
          
          - 
          - rbs = r1 &#8211; Math.abs(i);
          
          - 
          - rsum += r[yi] * rbs;
          
          - gsum += g[yi] * rbs;
          
          - bsum += b[yi] * rbs;
          
          - 
          - <span class="keyword">if</span> (i > <span class="number"></span>) {
          
          - rinsum += sir[<span class="number"></span>];
          
          - ginsum += sir[<span class="number">1</span>];
          
          - binsum += sir[<span class="number">2</span>];
          
          - } <span class="keyword">else</span> {
          
          - routsum += sir[<span class="number"></span>];
          
          - goutsum += sir[<span class="number">1</span>];
          
          - boutsum += sir[<span class="number">2</span>];
          
          - }
          
          - 
          - <span class="keyword">if</span> (i < hm) {
          
          - yp += w;
          
          - }
          
          - }
          
          - yi = x;
          
          - stackpointer = radius;
          
          - <span class="keyword">for</span> (y = <span class="number"></span>; y < h; y++) {
          
          - <span class="comment">// Preserve alpha channel: ( 0xff000000 & pix[yi] )</span>
          
          - pix[yi] = (<span class="number">0xff000000</span> & pix[yi]) | (dv[rsum] << <span class="number">16</span>) | (dv[gsum] << <span class="number">8</span>) | dv[bsum];
          
          - 
          - rsum -= routsum;
          
          - gsum -= goutsum;
          
          - bsum -= boutsum;
          
          - 
          - stackstart = stackpointer &#8211; radius + div;
          
          - sir = stack[stackstart % div];
          
          - 
          - routsum -= sir[<span class="number"></span>];
          
          - goutsum -= sir[<span class="number">1</span>];
          
          - boutsum -= sir[<span class="number">2</span>];
          
          - 
          - <span class="keyword">if</span> (x == <span class="number"></span>) {
          
          - vmin[y] = Math.min(y + r1, hm) * w;
          
          - }
          
          - p = x + vmin[y];
          
        
      </div>
    </div>
  
  
  - sir[<span class="number"></span>] = r[p];
  
  - sir[<span class="number">1</span>] = g[p];
  
  - sir[<span class="number">2</span>] = b[p];
  
  - 
  - rinsum += sir[<span class="number"></span>];
  
  - ginsum += sir[<span class="number">1</span>];
  
  - binsum += sir[<span class="number">2</span>];
  
  - 
  - rsum += rinsum;
  
  - gsum += ginsum;
  
  - bsum += binsum;
  
  - 
  - stackpointer = (stackpointer + <span class="number">1</span>) % div;
  
  - sir = stack[stackpointer];
  
  - 
  - routsum += sir[<span class="number"></span>];
  
  - goutsum += sir[<span class="number">1</span>];
  
  - boutsum += sir[<span class="number">2</span>];
  
  - 
  - rinsum -= sir[<span class="number"></span>];
  
  - ginsum -= sir[<span class="number">1</span>];
  
  - binsum -= sir[<span class="number">2</span>];
  
  - 
  - yi += w;
  
  - }
  
  - }
  
  - 
  - bitmap.setPixels(pix, <span class="number"></span>, w, <span class="number"></span>, <span class="number"></span>, w, h);
  
  - 
  - <span class="keyword">return</span> (bitmap);
  
  - }
这里的方法也可以实现高斯模糊的效果,但使用了特殊的算法,比第一种可以快很多,但比起RenderScript还是慢一些
(示例来源 [Android高级模糊技术](http://blog.jobbole.com/63894/))

实现YAHOO天气的动态模糊效果

YAHOO天气中的背景会随着手指上滑模糊程度加深,实际使用中发现怎么都达不到那样流畅的效果,因为手势刷新的速度很快,每一帧都去重新模糊计算一遍,还是会有延迟,造成页面卡顿。后来在一次偶然的开发中发现其实不需要每一帧都重新去模糊一遍,而是将图片最大程度模糊一次,之后和原图叠加,通过改变叠加的模糊图片的alpha值来达到不同程度的模糊效果。下面是一个例子,可以看到随着模糊图片alpha值的变化,叠加后产生不同程度的模糊效果。

随滑动变换alpha值的代码如下

    **[java]** [view plain](http://blog.csdn.net/xu_fu/article/details/23131241#)[copy](http://blog.csdn.net/xu_fu/article/details/23131241#)[print](http://blog.csdn.net/xu_fu/article/details/23131241#)[?](http://blog.csdn.net/xu_fu/article/details/23131241#)
  

  
  <div>
    <embed id="ZeroClipboardMovie_4" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="29" height="15" align="middle" name="ZeroClipboardMovie_4">
    </embed>
  </div>
</div>
- mBlurImage.setOnTouchListener(<span class="keyword">new</span> OnTouchListener() {

- 
- <span class="keyword">private</span> <span class="keyword">float</span> mLastY;

- 
- <span class="annotation">@Override</span>

- <span class="keyword">public</span> <span class="keyword">boolean</span> onTouch(View v, MotionEvent event) {

- <span class="keyword">switch</span> (event.getAction()) {

- <span class="keyword">case</span> MotionEvent.ACTION_DOWN:

- mLastY = event.getY();

- <span class="keyword">break</span>;

- <span class="keyword">case</span> MotionEvent.ACTION_MOVE:

- <span class="keyword">float</span> y = event.getY();

- <span class="keyword">float</span> alphaDelt = (y &#8211; mLastY) / <span class="number">1000</span>;

- <span class="keyword">float</span> alpha = mBlurImage.getAlpha() + alphaDelt;

- <span class="keyword">if</span> (alpha > <span class="number">1.0</span>) {

- alpha = <span class="number">1</span>.0f;

- } <span class="keyword">else</span> <span class="keyword">if</span> (alpha < <span class="number">0.0</span>) {

- alpha = <span class="number"></span>.0f;

- }

- mTextView.setText(String.valueOf(alpha));

- mBlurImage.setAlpha(alpha);

- <span class="keyword">break</span>;

- <span class="keyword">case</span> MotionEvent.ACTION_UP:

- <span class="keyword">break</span>;

- }

- <span class="keyword">return</span> <span class="keyword">true</span>;

- }

- });

示例代码下载 http://download.csdn.net/detail/xu_fu/7628139

图:   

效果图:

核心自然是高斯算法,这里没有深究其中的算法实现,只是项目实现而已。





引用代码:
  /** 水平方向模糊度 */

private static float hRadius = 10; /** 竖直方向模糊度 / private static float vRadius = 10; /* 模糊迭代度 */ private static int iterations = 7;

<div>
  <div id="highlighter_304250" class="syntaxhighlighter nogutter java">
    <table border="0" cellspacing="0" cellpadding="0">
      <tr>
        <td class="code">
          <div class="container">
            <div class="line number1 index0 alt2">
              `/**`
            </div>
            
            <div class="line number2 index1 alt1">
              `     ``* 高斯模糊`
            </div>
            
            <div class="line number3 index2 alt2">
              `     ``*/`
            </div>
            
            <div class="line number4 index3 alt1">
              `    ``public` `static` `Drawable BoxBlurFilter(Bitmap bmp) {`
            </div>
            
            <div class="line number5 index4 alt2">
              `        ``int` `width = bmp.getWidth();`
            </div>
            
            <div class="line number6 index5 alt1">
              `        ``int` `height = bmp.getHeight();`
            </div>
            
            <div class="line number7 index6 alt2">
              `        ``int``[] inPixels = ``new` `int``[width * height];`
            </div>
            
            <div class="line number8 index7 alt1">
              `        ``int``[] outPixels = ``new` `int``[width * height];`
            </div>
            
            <div class="line number9 index8 alt2">
              `        ``Bitmap bitmap = Bitmap.createBitmap(width, height,Bitmap.Config.ARGB_8888);`
            </div>
            
            <div class="line number10 index9 alt1">
              `        ``bmp.getPixels(inPixels, ````, width, ````, ````, width, height);`
            </div>
            
            <div class="line number11 index10 alt2">
              `        ``for` `(``int` `i = ````; i &lt; iterations; i++) {`
            </div>
            
            <div class="line number12 index11 alt1">
              `            ``blur(inPixels, outPixels, width, height, hRadius);`
            </div>
            
            <div class="line number13 index12 alt2">
              `            ``blur(outPixels, inPixels, height, width, vRadius);`
            </div>
            
            <div class="line number14 index13 alt1">
              `        ``}`
            </div>
            
            <div class="line number15 index14 alt2">
              `        ``blurFractional(inPixels, outPixels, width, height, hRadius);`
            </div>
            
            <div class="line number16 index15 alt1">
              `        ``blurFractional(outPixels, inPixels, height, width, vRadius);`
            </div>
            
            <div class="line number17 index16 alt2">
              `        ``bitmap.setPixels(inPixels, ````, width, ````, ````, width, height);`
            </div>
            
            <div class="line number18 index17 alt1">
              `        ``Drawable drawable = ``new` `BitmapDrawable(bitmap);`
            </div>
            
            <div class="line number19 index18 alt2">
              `        ``return` `drawable;`
            </div>
            
            <div class="line number20 index19 alt1">
              `    ``}`
            </div>
          </div>
        </td>
      </tr>
    </table>
  </div>
</div>
核心算法:
`public` `static` `void` `blur(``int``[] in, ``int``[] out, ``int` `width, ``int` `height,`
          <div class="line number2 index1 alt1">
            `            ``float` `radius) {`
          </div>
          
          <div class="line number3 index2 alt2">
            `        ``int` `widthMinus1 = width - ``1``;`
          </div>
          
          <div class="line number4 index3 alt1">
            `        ``int` `r = (``int``) radius;`
          </div>
          
          <div class="line number5 index4 alt2">
            `        ``int` `tableSize = ``2` `* r + ``1``;`
          </div>
          
          <div class="line number6 index5 alt1">
            `        ``int` `divide[] = ``new` `int``[``256` `* tableSize];`
          </div>
          
          <div class="line number7 index6 alt2">
          </div>
          
          <div class="line number8 index7 alt1">
            `        ``for` `(``int` `i = ````; i &lt; ``256` `* tableSize; i++)`
          </div>
          
          <div class="line number9 index8 alt2">
            `            ``divide[i] = i / tableSize;`
          </div>
          
          <div class="line number10 index9 alt1">
          </div>
          
          <div class="line number11 index10 alt2">
            `        ``int` `inIndex = ````;`
          </div>
          
          <div class="line number12 index11 alt1">
          </div>
          
          <div class="line number13 index12 alt2">
            `        ``for` `(``int` `y = ````; y &lt; height; y++) {`
          </div>
          
          <div class="line number14 index13 alt1">
            `            ``int` `outIndex = y;`
          </div>
          
          <div class="line number15 index14 alt2">
            `            ``int` `ta = ````, tr = ````, tg = ````, tb = ````;`
          </div>
          
          <div class="line number16 index15 alt1">
          </div>
          
          <div class="line number17 index16 alt2">
            `            ``for` `(``int` `i = -r; i &lt;= r; i++) {`
          </div>
          
          <div class="line number18 index17 alt1">
            `                ``int` `rgb = in[inIndex + clamp(i, ````, width - ``1``)];`
          </div>
          
          <div class="line number19 index18 alt2">
            `                ``ta += (rgb &gt;&gt; ``24``) & ``0xff``;`
          </div>
          
          <div class="line number20 index19 alt1">
            `                ``tr += (rgb &gt;&gt; ``16``) & ``0xff``;`
          </div>
          
          <div class="line number21 index20 alt2">
            `                ``tg += (rgb &gt;&gt; ``8``) & ``0xff``;`
          </div>
          
          <div class="line number22 index21 alt1">
            `                ``tb += rgb & ``0xff``;`
          </div>
          
          <div class="line number23 index22 alt2">
            `            ``}`
          </div>
          
          <div class="line number24 index23 alt1">
          </div>
          
          <div class="line number25 index24 alt2">
            `            ``for` `(``int` `x = ````; x &lt; width; x++) {`
          </div>
          
          <div class="line number26 index25 alt1">
            `                ``out[outIndex] = (divide[ta] &lt;&lt; ``24``) | (divide[tr] &lt;&lt; ``16``)`
          </div>
          
          <div class="line number27 index26 alt2">
            `                        ``| (divide[tg] &lt;&lt; ``8``) | divide[tb];`
          </div>
          
          <div class="line number28 index27 alt1">
          </div>
          
          <div class="line number29 index28 alt2">
            `                ``int` `i1 = x + r + ``1``;`
          </div>
          
          <div class="line number30 index29 alt1">
            `                ``if` `(i1 &gt; widthMinus1)`
          </div>
          
          <div class="line number31 index30 alt2">
            `                    ``i1 = widthMinus1;`
          </div>
          
          <div class="line number32 index31 alt1">
            `                ``int` `i2 = x - r;`
          </div>
          
          <div class="line number33 index32 alt2">
            `                ``if` `(i2 &lt; ````)`
          </div>
          
          <div class="line number34 index33 alt1">
            `                    ``i2 = ````;`
          </div>
          
          <div class="line number35 index34 alt2">
            `                ``int` `rgb1 = in[inIndex + i1];`
          </div>
          
          <div class="line number36 index35 alt1">
            `                ``int` `rgb2 = in[inIndex + i2];`
          </div>
          
          <div class="line number37 index36 alt2">
          </div>
          
          <div class="line number38 index37 alt1">
            `                ``ta += ((rgb1 &gt;&gt; ``24``) & ``0xff``) - ((rgb2 &gt;&gt; ``24``) & ``0xff``);`
          </div>
          
          <div class="line number39 index38 alt2">
            `                ``tr += ((rgb1 & ``0xff0000``) - (rgb2 & ``0xff0000``)) &gt;&gt; ``16``;`
          </div>
          
          <div class="line number40 index39 alt1">
            `                ``tg += ((rgb1 & ``0xff00``) - (rgb2 & ``0xff00``)) &gt;&gt; ``8``;`
          </div>
          
          <div class="line number41 index40 alt2">
            `                ``tb += (rgb1 & ``0xff``) - (rgb2 & ``0xff``);`
          </div>
          
          <div class="line number42 index41 alt1">
            `                ``outIndex += height;`
          </div>
          
          <div class="line number43 index42 alt2">
            `            ``}`
          </div>
          
          <div class="line number44 index43 alt1">
            `            ``inIndex += width;`
          </div>
          
          <div class="line number45 index44 alt2">
            `        ``}`
          </div>
          
          <div class="line number46 index45 alt1">
            `    ``}`
          </div>
          
          <div class="line number47 index46 alt2">
          </div>
          
          <div class="line number48 index47 alt1">
            `    ``public` `static` `void` `blurFractional(``int``[] in, ``int``[] out, ``int` `width,`
          </div>
          
          <div class="line number49 index48 alt2">
            `            ``int` `height, ``float` `radius) {`
          </div>
          
          <div class="line number50 index49 alt1">
            `        ``radius -= (``int``) radius;`
          </div>
          
          <div class="line number51 index50 alt2">
            `        ``float` `f = ``1``.0f / (``1` `+ ``2` `* radius);`
          </div>
          
          <div class="line number52 index51 alt1">
            `        ``int` `inIndex = ````;`
          </div>
          
          <div class="line number53 index52 alt2">
          </div>
          
          <div class="line number54 index53 alt1">
            `        ``for` `(``int` `y = ````; y &lt; height; y++) {`
          </div>
          
          <div class="line number55 index54 alt2">
            `            ``int` `outIndex = y;`
          </div>
          
          <div class="line number56 index55 alt1">
          </div>
          
          <div class="line number57 index56 alt2">
            `            ``out[outIndex] = in[````];`
          </div>
          
          <div class="line number58 index57 alt1">
            `            ``outIndex += height;`
          </div>
          
          <div class="line number59 index58 alt2">
            `            ``for` `(``int` `x = ``1``; x &lt; width - ``1``; x++) {`
          </div>
          
          <div class="line number60 index59 alt1">
            `                ``int` `i = inIndex + x;`
          </div>
          
          <div class="line number61 index60 alt2">
            `                ``int` `rgb1 = in[i - ``1``];`
          </div>
          
          <div class="line number62 index61 alt1">
            `                ``int` `rgb2 = in[i];`
          </div>
          
          <div class="line number63 index62 alt2">
            `                ``int` `rgb3 = in[i + ``1``];`
          </div>
          
          <div class="line number64 index63 alt1">
          </div>
          
          <div class="line number65 index64 alt2">
            `                ``int` `a1 = (rgb1 &gt;&gt; ``24``) & ``0xff``;`
          </div>
          
          <div class="line number66 index65 alt1">
            `                ``int` `r1 = (rgb1 &gt;&gt; ``16``) & ``0xff``;`
          </div>
          
          <div class="line number67 index66 alt2">
            `                ``int` `g1 = (rgb1 &gt;&gt; ``8``) & ``0xff``;`
          </div>
          
          <div class="line number68 index67 alt1">
            `                ``int` `b1 = rgb1 & ``0xff``;`
          </div>
          
          <div class="line number69 index68 alt2">
            `                ``int` `a2 = (rgb2 &gt;&gt; ``24``) & ``0xff``;`
          </div>
          
          <div class="line number70 index69 alt1">
            `                ``int` `r2 = (rgb2 &gt;&gt; ``16``) & ``0xff``;`
          </div>
          
          <div class="line number71 index70 alt2">
            `                ``int` `g2 = (rgb2 &gt;&gt; ``8``) & ``0xff``;`
          </div>
          
          <div class="line number72 index71 alt1">
            `                ``int` `b2 = rgb2 & ``0xff``;`
          </div>
          
          <div class="line number73 index72 alt2">
            `                ``int` `a3 = (rgb3 &gt;&gt; ``24``) & ``0xff``;`
          </div>
          
          <div class="line number74 index73 alt1">
            `                ``int` `r3 = (rgb3 &gt;&gt; ``16``) & ``0xff``;`
          </div>
          
          <div class="line number75 index74 alt2">
            `                ``int` `g3 = (rgb3 &gt;&gt; ``8``) & ``0xff``;`
          </div>
          
          <div class="line number76 index75 alt1">
            `                ``int` `b3 = rgb3 & ``0xff``;`
          </div>
          
          <div class="line number77 index76 alt2">
            `                ``a1 = a2 + (``int``) ((a1 + a3) * radius);`
          </div>
          
          <div class="line number78 index77 alt1">
            `                ``r1 = r2 + (``int``) ((r1 + r3) * radius);`
          </div>
          
          <div class="line number79 index78 alt2">
            `                ``g1 = g2 + (``int``) ((g1 + g3) * radius);`
          </div>
          
          <div class="line number80 index79 alt1">
            `                ``b1 = b2 + (``int``) ((b1 + b3) * radius);`
          </div>
          
          <div class="line number81 index80 alt2">
            `                ``a1 *= f;`
          </div>
          
          <div class="line number82 index81 alt1">
            `                ``r1 *= f;`
          </div>
          
          <div class="line number83 index82 alt2">
            `                ``g1 *= f;`
          </div>
          
          <div class="line number84 index83 alt1">
            `                ``b1 *= f;`
          </div>
          
          <div class="line number85 index84 alt2">
            `                ``out[outIndex] = (a1 &lt;&lt; ``24``) | (r1 &lt;&lt; ``16``) | (g1 &lt;&lt; ``8``) | b1;`
          </div>
          
          <div class="line number86 index85 alt1">
            `                ``outIndex += height;`
          </div>
          
          <div class="line number87 index86 alt2">
            `            ``}`
          </div>
          
          <div class="line number88 index87 alt1">
            `            ``out[outIndex] = in[width - ``1``];`
          </div>
          
          <div class="line number89 index88 alt2">
            `            ``inIndex += width;`
          </div>
          
          <div class="line number90 index89 alt1">
            `        ``}`
          </div>
          
          <div class="line number91 index90 alt2">
            `    ``}`
          </div>
          
          <div class="line number92 index91 alt1">
          </div>
          
          <div class="line number93 index92 alt2">
            `    ``public` `static` `int` `clamp(``int` `x, ``int` `a, ``int` `b) {`
          </div>
          
          <div class="line number94 index93 alt1">
            `        ``return` `(x &lt; a) ? a : (x &gt; b) ? b : x;`
          </div>
          
          <div class="line number95 index94 alt2">
            `    ``}`
          </div>
        </div>
      </td>
    </tr>
  </table>
</div>

 

💬 评论