這篇將講到圖片特效處理的模糊效果。跟前面一樣是對像素點進行處理,算法是通用的,但耗時會更長,至於為什么,看了下面的代碼你就會明白。
算法:
一、簡單算法:將像素點周圍八個點包括自身一共九個點的RGB值分別相加后平均,作為當前像素點的RGB值,即可實現效果。
舉例:
ABC
DEF
GHI
假如當前點是E,那么會有:
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.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值類似。
二、采用高斯模糊:
高斯矩陣:
int[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 }; nt[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 };
算法是:將九個點的RGB值分別與高斯矩陣中的對應項相乘的和,然后再除以一個相應的值作為當前像素點的RGB值。
舉例:(還是上面的九個點)
假如當前點是E,那么會有:
int delta = 16; 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 int delta = 16; 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的效果。
處理效果:
原圖片:
兩種處理方式的代碼:
/** * 模糊效果 * @param bmp * @return */ private Bitmap blurImage(Bitmap bmp) { int width = bmp.getWidth(); int height = bmp.getHeight(); Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); int pixColor = 0; int newR = 0; int newG = 0; int newB = 0; int newColor = 0; int[][] colors = new int[9][3]; for (int i = 1, length = width - 1; i < length; i++) { for (int k = 1, len = height - 1; k < len; k++) { for (int m = 0; m < 9; m++) { int s = 0; int p = 0; switch(m) { case 0: s = i - 1; p = k - 1; break; case 1: s = i; p = k - 1; break; case 2: s = i + 1; p = k - 1; break; case 3: s = i + 1; p = k; break; case 4: s = i + 1; p = k + 1; break; case 5: s = i; p = k + 1; break; case 6: s = i - 1; p = k + 1; break; case 7: s = i - 1; p = k; break; case 8: s = i; p = k; } pixColor = bmp.getPixel(s, p); colors[m][0] = Color.red(pixColor); colors[m][1] = Color.green(pixColor); colors[m][2] = Color.blue(pixColor); } for (int m = 0; m < 9; m++) { newR += colors[m][0]; newG += colors[m][1]; newB += colors[m][2]; } newR = (int) (newR / 9F); newG = (int) (newG / 9F); newB = (int) (newB / 9F); newR = Math.min(255, Math.max(0, newR)); newG = Math.min(255, Math.max(0, newG)); newB = Math.min(255, Math.max(0, newB)); newColor = Color.argb(255, newR, newG, newB); bitmap.setPixel(i, k, newColor); newR = 0; newG = 0; newB = 0; } } return bitmap; } /** * 柔化效果(高斯模糊)(優化后比上面快三倍) * @param bmp * @return */ private Bitmap blurImageAmeliorate(Bitmap bmp) { long start = System.currentTimeMillis(); // 高斯矩陣 int[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 }; int width = bmp.getWidth(); int height = bmp.getHeight(); Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); int pixR = 0; int pixG = 0; int pixB = 0; int pixColor = 0; int newR = 0; int newG = 0; int newB = 0; int delta = 16; // 值越小圖片會越亮,越大則越暗 int idx = 0; int[] pixels = new int[width * height]; bmp.getPixels(pixels, 0, width, 0, 0, width, height); for (int i = 1, length = height - 1; i < length; i++) { for (int k = 1, len = width - 1; k < len; k++) { idx = 0; for (int m = -1; m <= 1; m++) { for (int n = -1; n <= 1; n++) { pixColor = pixels[(i + m) * width + k + n]; pixR = Color.red(pixColor); pixG = Color.green(pixColor); pixB = Color.blue(pixColor); newR = newR + (int) (pixR * gauss[idx]); newG = newG + (int) (pixG * gauss[idx]); newB = newB + (int) (pixB * gauss[idx]); idx++; } } newR /= delta; newG /= delta; newB /= delta; newR = Math.min(255, Math.max(0, newR)); newG = Math.min(255, Math.max(0, newG)); newB = Math.min(255, Math.max(0, newB)); pixels[i * width + k] = Color.argb(255, newR, newG, newB); newR = 0; newG = 0; newB = 0; } } bitmap.setPixels(pixels, 0, width, 0, 0, width, height); long end = System.currentTimeMillis(); Log.d("may", "used time="+(end - start)); return bitmap; }
/** * 模糊效果 * @param bmp * @return */ private Bitmap blurImage(Bitmap bmp) { int width = bmp.getWidth(); int height = bmp.getHeight(); Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); int pixColor = 0; int newR = 0; int newG = 0; int newB = 0; int newColor = 0; int[][] colors = new int[9][3]; for (int i = 1, length = width - 1; i < length; i++) { for (int k = 1, len = height - 1; k < len; k++) { for (int m = 0; m < 9; m++) { int s = 0; int p = 0; switch(m) { case 0: s = i - 1; p = k - 1; break; case 1: s = i; p = k - 1; break; case 2: s = i + 1; p = k - 1; break; case 3: s = i + 1; p = k; break; case 4: s = i + 1; p = k + 1; break; case 5: s = i; p = k + 1; break; case 6: s = i - 1; p = k + 1; break; case 7: s = i - 1; p = k; break; case 8: s = i; p = k; } pixColor = bmp.getPixel(s, p); colors[m][0] = Color.red(pixColor); colors[m][1] = Color.green(pixColor); colors[m][2] = Color.blue(pixColor); } for (int m = 0; m < 9; m++) { newR += colors[m][0]; newG += colors[m][1]; newB += colors[m][2]; } newR = (int) (newR / 9F); newG = (int) (newG / 9F); newB = (int) (newB / 9F); newR = Math.min(255, Math.max(0, newR)); newG = Math.min(255, Math.max(0, newG)); newB = Math.min(255, Math.max(0, newB)); newColor = Color.argb(255, newR, newG, newB); bitmap.setPixel(i, k, newColor); newR = 0; newG = 0; newB = 0; } } return bitmap; } /** * 柔化效果(高斯模糊)(優化后比上面快三倍) * @param bmp * @return */ private Bitmap blurImageAmeliorate(Bitmap bmp) { long start = System.currentTimeMillis(); // 高斯矩陣 int[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 }; int width = bmp.getWidth(); int height = bmp.getHeight(); Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); int pixR = 0; int pixG = 0; int pixB = 0; int pixColor = 0; int newR = 0; int newG = 0; int newB = 0; int delta = 16; // 值越小圖片會越亮,越大則越暗 int idx = 0; int[] pixels = new int[width * height]; bmp.getPixels(pixels, 0, width, 0, 0, width, height); for (int i = 1, length = height - 1; i < length; i++) { for (int k = 1, len = width - 1; k < len; k++) { idx = 0; for (int m = -1; m <= 1; m++) { for (int n = -1; n <= 1; n++) { pixColor = pixels[(i + m) * width + k + n]; pixR = Color.red(pixColor); pixG = Color.green(pixColor); pixB = Color.blue(pixColor); newR = newR + (int) (pixR * gauss[idx]); newG = newG + (int) (pixG * gauss[idx]); newB = newB + (int) (pixB * gauss[idx]); idx++; } } newR /= delta; newG /= delta; newB /= delta; newR = Math.min(255, Math.max(0, newR)); newG = Math.min(255, Math.max(0, newG)); newB = Math.min(255, Math.max(0, newB)); pixels[i * width + k] = Color.argb(255, newR, newG, newB); newR = 0; newG = 0; newB = 0; } } bitmap.setPixels(pixels, 0, width, 0, 0, width, height); long end = System.currentTimeMillis(); Log.d("may", "used time="+(end - start)); return bitmap; }
在優化后的代碼中要注意了,pixels數組不能超過規定的大小,也就是說圖片的尺寸不能太大,否則會棧內存溢出。
轉自:http://blog.csdn.net/sjf0115/article/details/7266998