模糊效果

这篇将讲到图片特效处理的模糊效果。跟前面一样是对像素点进行处理,算法是通用的,但耗时会更长,至于为什么,看了下面的代码你就会明白。

算法:

一、简单算法:将像素点周围八个点包括自身一共九个点的RGB值分别相加后平均,作为当前像素点的RGB值,即可实现效果。

举例:

ABC

DEF

GHI

假如当前点是E,那么会有:

[java] view plaincopy
 
  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值 
[java] view plaincopy
 
  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 plaincopy
 
  1. int[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 }; 
[java] view plaincopy
 
  1. int[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 };  

算法是:将九个点的RGB值分别与高斯矩阵中的对应项相乘的和,然后再除以一个相应的值作为当前像素点的RGB值。

举例:(还是上面的九个点)
假如当前点是E,那么会有:

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

在优化后的代码中要注意了,pixels数组不能超过规定的大小,也就是说图片的尺寸不能太大,否则会栈内存溢出。

原文地址:https://www.cnblogs.com/clarence/p/3837851.html