一种基于Android Bitmap和数组操作的简单卷积图像处理函数
原理来自于知乎文章:
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 )效果:
原图:
处理后: