一种基于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 )效果:

原图:

处理后:

猜你喜欢

转载自blog.csdn.net/cjzjolly/article/details/84966503