一種基於Android Bitmap和陣列操作的簡單卷積影象處理函式
阿新 • • 發佈:2018-12-16
原理來自於知乎文章:
https://zhuanlan.zhihu.com/p/43738099+
我的實現函式:
/**使用卷積核對影象進行處理**/ private static float sharpeningEffect[] = new float[]{-1,-1,-1,-1,9,-1,-1,-1,-1};//銳化效果 private static float noEffect[] = new float[]{0,0,0,0,1,0,0,0,0}; //原圖(測試用) private static float effect2[] = new float[]{1,1,1,1,-7,1,1,1,1}; //強調邊緣 private static float[] effect3 = {0.1f,0.1f,0.1f,0.1f,0.1f,0.1f,0.1f,0.1f,0.1f};//平滑效果 private static float[] effect4 = {1/9f,1/9f,1/9f,1/9f,1/9f,1/9f,1/9f,1/9f,1/9f};//平滑效果 private static float[] effect5 = {1/16f,2/16f,1/16f,2/16f,4/16f,2/16f,1/16f,2/16f,1/16f};//高斯平滑 private static float[] effect6 = {1,1,1,0,0,0,-1,-1,-1};//豎向邊緣 public static Bitmap bitmapConvolution(Bitmap bitmap){ float effect[] = effect2; int[] newPixels = new int[bitmap.getWidth() * bitmap.getHeight()]; for(int y = 0; y < bitmap.getHeight(); y++) { for (int x = 0; x < bitmap.getWidth(); x++) { int newargb[][] = new int[9][4]; int count = 0; for (int offsetY = -1; offsetY <= 1; offsetY++) { for (int offsetX = -1; offsetX <= 1; offsetX++) { int newX = x + offsetX; int newY = y + offsetY; if(!(newX < 0 || newY < 0 || newX >= bitmap.getWidth() || newY >= bitmap.getHeight())){ int pixel = bitmap.getPixel(newX, newY); newargb[count][0] = pixel >> 24 & 0xFF; newargb[count][1] = pixel >> 16 & 0xFF; newargb[count][2] = pixel >> 8 & 0xFF; newargb[count][3] = pixel & 0xFF; } else { // newargb[count][0] = newargb[count][1] = newargb[count][2] = newargb[count][3] = 0xFF; } count++; } } int resultArgb[] = new int[4]; for(int i = 0; i < effect.length; i++){ for(int j = 0; j < 4; j++){ resultArgb[j] += (int) (effect[effect.length - i - 1] * (float)newargb[i][j]); //第i畫素的第j顏色通道乘以第i個卷積核 } } for(int i = 0; i < resultArgb.length; i++){ resultArgb[i] = resultArgb[i] < 0 ? 0 : resultArgb[i] > 255 ? 255 : resultArgb[i]; } newPixels[y * bitmap.getWidth() + x] |= resultArgb[0] << 24; newPixels[y * bitmap.getWidth() + x] |= resultArgb[1] << 16; newPixels[y * bitmap.getWidth() + x] |= resultArgb[2] << 8; newPixels[y * bitmap.getWidth() + x] |= resultArgb[3]; } } return Bitmap.createBitmap(newPixels, bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); }
大家可以替換effect裡面使用的矩陣來更替影象處理的效果,我預設使用的是“強調邊緣”效果
效果如下:
原圖:
處理後:
原圖:
處理後:
改為使用“高斯模糊”(effect5 )效果:
原圖:
處理後: