1. 程式人生 > >android圖片特效處理之模糊效果

android圖片特效處理之模糊效果

這篇將講到圖片特效處理的模糊效果。跟前面一樣是對畫素點進行處理,演算法是通用的,但耗時會更長,至於為什麼,看了下面的程式碼你就會明白。

演算法:

一、簡單演算法:將畫素點周圍八個點包括自身一共九個點的RGB值分別相加後平均,作為當前畫素點的RGB值,即可實現效果。

舉例:

ABC

DEF

GHI

假如當前點是E,那麼會有:

[java] view plaincopyprint?
  1. E.r = (A.r + B.r + C.r + D.r + E.r + F.r + G.r + H.r + I.r) /9// r表示的是E畫素點RGB值的R值

E畫素點的GB值類似。

二、採用高斯模糊:

高斯矩陣:

[java] view plaincopyprint?
  1. int[] gauss = newint[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 }; 
演算法是:將九個點的RGB值分別與高斯矩陣中的對應項相乘的和,然後再除以一個相應的值作為當前畫素點的RGB值。

舉例:(還是上面的九個點)
假如當前點是E,那麼會有:

[java] view plaincopyprint?
  1. int delta = 16
  2. E.r =( A.r * gauss[0
    ] + B.r * gauss[1] + C.r * gauss[2] + D.r * gauss[3] + E.r * gauss[4] + F.r * gauss[5] + G.r * gauss[6] + H.r * gauss[7] + I.r * gauss[8]) / delta 
E畫素點的GB值類似,delta的取值貌似沒有規定值,可以自己設定任意值,但要想達到效果,能設的值很少,下面圖片是值為16的效果。
處理效果:

原圖片:


處理後:

兩種處理方式的程式碼:

[java] view plaincopyprint?
  1. /**
  2.      * 模糊效果
  3.      * @param bmp
  4.      * @return
  5.      */
  6.     private Bitmap blurImage(Bitmap bmp) 
  7.     { 
  8.         int width = bmp.getWidth(); 
  9.         int height = bmp.getHeight(); 
  10.         Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); 
  11.         int pixColor = 0
  12.         int newR = 0
  13.         int newG = 0
  14.         int newB = 0
  15.         int newColor = 0
  16.         int[][] colors = newint[9][3]; 
  17.         for (int i = 1, length = width - 1; i < length; i++) 
  18.         { 
  19.             for (int k = 1, len = height - 1; k < len; k++) 
  20.             { 
  21.                 for (int m = 0; m < 9; m++) 
  22.                 { 
  23.                     int s = 0
  24.                     int p = 0
  25.                     switch(m) 
  26.                     { 
  27.                     case0
  28.                         s = i - 1
  29.                         p = k - 1
  30.                         break
  31.                     case1
  32.                         s = i; 
  33.                         p = k - 1
  34.                         break
  35.                     case2
  36.                         s = i + 1
  37.                         p = k - 1
  38.                         break
  39.                     case3
  40.                         s = i + 1
  41.                         p = k; 
  42.                         break
  43.                     case4
  44.                         s = i + 1
  45.                         p = k + 1
  46.                         break
  47.                     case5
  48.                         s = i; 
  49.                         p = k + 1
  50.                         break
  51.                     case6
  52.                         s = i - 1
  53.                         p = k + 1
  54.                         break
  55.                     case7
  56.                         s = i - 1
  57.                         p = k; 
  58.                         break
  59.                     case8
  60.                         s = i; 
  61.                         p = k; 
  62.                     } 
  63.                     pixColor = bmp.getPixel(s, p); 
  64.                     colors[m][0] = Color.red(pixColor); 
  65.                     colors[m][1] = Color.green(pixColor); 
  66.                     colors[m][2] = Color.blue(pixColor); 
  67.                 } 
  68.                 for (int m = 0; m < 9; m++) 
  69.                 { 
  70.                     newR += colors[m][0]; 
  71.                     newG += colors[m][1]; 
  72.                     newB += colors[m][2]; 
  73.                 } 
  74.                 newR = (int) (newR / 9F); 
  75.                 newG = (int) (newG / 9F); 
  76.                 newB = (int) (newB / 9F); 
  77.                 newR = Math.min(255, Math.max(0, newR)); 
  78.                 newG = Math.min(255, Math.max(0, newG)); 
  79.                 newB = Math.min(255, Math.max(0, newB)); 
  80.                 newColor = Color.argb(255, newR, newG, newB); 
  81.                 bitmap.setPixel(i, k, newColor); 
  82.                 newR = 0
  83.                 newG = 0
  84.                 newB = 0
  85.             } 
  86.         } 
  87.         return bitmap; 
  88.     } 
  89.     /**
  90.      * 柔化效果(高斯模糊)(優化後比上面快三倍)
  91.      * @param bmp
  92.      * @return
  93.      */
  94.     private Bitmap blurImageAmeliorate(Bitmap bmp) 
  95.     { 
  96.         long start = System.currentTimeMillis(); 
  97.         // 高斯矩陣
  98.         int[] gauss = newint[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 }; 
  99.         int width = bmp.getWidth(); 
  100.         int height = bmp.getHeight(); 
  101.         Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); 
  102.         int pixR = 0
  103.         int pixG = 0
  104.         int pixB = 0
  105.         int pixColor = 0
  106.         int newR = 0
  107.         int newG = 0
  108.         int newB = 0
  109.         int delta = 16; // 值越小圖片會越亮,越大則越暗
  110.         int idx = 0
  111.         int[] pixels = newint[width * height]; 
  112.         bmp.getPixels(pixels, 0, width, 0, 0, width, height); 
  113.         for (int i = 1, length = height - 1; i < length; i++) 
  114.         { 
  115.             for (int k = 1, len = width - 1; k < len; k++) 
  116.             { 
  117.                 idx = 0
  118.                 for (int m = -1; m <= 1; m++) 
  119.                 { 
  120.                     for (int n = -1; n <= 1; n++) 
  121.                     { 
  122.                         pixColor = pixels[(i + m) * width + k + n]; 
  123.                         pixR = Color.red(pixColor); 
  124.                         pixG = Color.green(pixColor); 
  125.                         pixB = Color.blue(pixColor); 
  126.                         newR = newR + (int) (pixR * gauss[idx]); 
  127.                         newG = newG + (int) (pixG * gauss[idx]); 
  128.                         newB = newB + (int) (pixB * gauss[idx]); 
  129.                         idx++; 
  130.                     } 
  131.                 } 
  132.                 newR /= delta; 
  133.                 newG /= delta; 
  134.                 newB /= delta; 
  135.                 newR = Math.min(255, Math.max(0, newR)); 
  136.                 newG = Math.min(255, Math.max(0, newG)); 
  137.                 newB = Math.min(255, Math.max(0, newB)); 
  138.                 pixels[i * width + k] = Color.argb(255, newR, newG, newB); 
  139.                 newR = 0
  140.                 newG = 0
  141.                 newB = 0
  142.             } 
  143.         } 
  144.         bitmap.setPixels(pixels, 0, width, 0, 0, width, height); 
  145.         long end = System.currentTimeMillis(); 
  146.         Log.d("may", "used time="+(end - start)); 
  147.         return bitmap; 
  148.     } 

在優化後的程式碼中要注意了,pixels陣列不能超過規定的大小,也就是說圖片的尺寸不能太大,否則會棧記憶體溢位。