JavaFX高斯模糊代码

代码如下:

import javafx.scene.image.PixelReader;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;

public class GaussBlur {
    //返回输入图片的高斯模糊效果图
    public WritableImage makeGaussBlur(WritableImage image) {
        float[][] kernal = get2DKernalData(1,3);
        int[][][] in3DImageData = get3DImageData(image);
        int[][][] out3DImageData = makeConvolution(in3DImageData,kernal);
        double peak = getRate(in3DImageData,out3DImageData);
        out3DImageData = makeNormal(out3DImageData,peak);

        WritableImage outImage = new WritableImage(out3DImageData.length,out3DImageData[0].length);
        PixelWriter pixel = outImage.getPixelWriter();

        for(int i=0;i<outImage.getWidth();i++) {
            for(int j=0;j<outImage.getHeight();j++) {
                int newPixel = argbToPixel(out3DImageData[i][j][0], out3DImageData[i][j][1], out3DImageData[i][j][2], out3DImageData[i][j][3]);
                pixel.setArgb(i, j, newPixel);

            }
        }

        return outImage;
    }

    private int argbToPixel(int alpha, int red, int green, int blue) {

        int newPixel = 0;
        newPixel += alpha;
        newPixel = newPixel << 8;
        newPixel += red;
        newPixel = newPixel << 8;
        newPixel += green;
        newPixel = newPixel << 8;
        newPixel += blue;

        return newPixel;

    }

    //获取二维高斯卷积内核算子矩阵
    public float[][] get2DKernalData(int n, float sigma) {  
        int size = 2*n +1;  
        float sigma22 = 2*sigma*sigma;  
        float sigma22PI = (float)Math.PI * sigma22;  
        float[][] kernalData = new float[size][size];  
        int row = 0;  
        for(int i=-n; i<=n; i++) {  
            int column = 0;  
            for(int j=-n; j<=n; j++) {  
                float xDistance = i*i;  
                float yDistance = j*j;  
                kernalData[row][column] = (float)Math.exp(-(xDistance + yDistance)/sigma22)/sigma22PI;  
                column++;  
            }  
            row++;  
        }  

        for(int i=0; i<size; i++) {  
            for(int j=0; j<size; j++) {  
                System.out.print("\t" + kernalData[i][j]);  
            }  
            System.out.println();  
            System.out.println("\t ---------------------------");  
        } 

        return kernalData;  
    }

    //对指定图片使用指定算子矩阵进行卷积运算,向内收缩两个像素
    public int[][][] makeConvolution(int[][][] in3DImageData,float[][] kernal) {
        int x = in3DImageData.length;
        int y = in3DImageData[0].length;
        int z = in3DImageData[0][0].length;

        int xf = kernal.length/2;
        int yf = kernal[0].length/2;

        int[][][] out3DImageData = new int[x][y][z];

        for(int i=xf;i<x-xf;i++) {
            for(int j=xf;j<y-yf;j++) {
                for(int k=1;k<z;k++) {
                    //a
                    out3DImageData[i][j][0] = in3DImageData[i][j][0];
                    //Red
                    out3DImageData[i][j][1] = (int) (in3DImageData[i][j][1] * kernal[xf][yf] +
                                              in3DImageData[i][j-1][1] * kernal[xf][yf-1] +
                                              in3DImageData[i][j+1][1] * kernal[xf][yf+1] +
                                              in3DImageData[i-1][j][1] * kernal[xf-1][yf] +
                                              in3DImageData[i-1][j-1][1] * kernal[xf-1][yf-1] +
                                              in3DImageData[i-1][j+1][1] * kernal[xf-1][yf+1] +
                                              in3DImageData[i+1][j][1] * kernal[xf+1][yf] +
                                              in3DImageData[i+1][j-1][1] * kernal[xf+1][yf-1] + 
                                              in3DImageData[i+1][j+1][1] * kernal[xf+1][yf+1]);
                    //Green
                    out3DImageData[i][j][2] = (int) (in3DImageData[i][j][2] * kernal[xf][yf] +
                                              in3DImageData[i][j-1][2] * kernal[xf][yf-1] +
                                              in3DImageData[i][j+1][2] * kernal[xf][yf+1] +
                                              in3DImageData[i-1][j][2] * kernal[xf-1][yf] +
                                              in3DImageData[i-1][j-1][2] * kernal[xf-1][yf-1] +
                                              in3DImageData[i-1][j+1][2] * kernal[xf-1][yf+1] +
                                              in3DImageData[i+1][j][2] * kernal[xf+1][yf] +
                                              in3DImageData[i+1][j-1][2] * kernal[xf+1][yf-1] + 
                                              in3DImageData[i+1][j+1][2] * kernal[xf+1][yf+1]);
                    //Blue
                    out3DImageData[i][j][3] = (int) (in3DImageData[i][j][3] * kernal[xf][yf] +
                                              in3DImageData[i][j-1][3] * kernal[xf][yf-1] +
                                              in3DImageData[i][j+1][3] * kernal[xf][yf+1] +
                                              in3DImageData[i-1][j][3] * kernal[xf-1][yf] +
                                              in3DImageData[i-1][j-1][3] * kernal[xf-1][yf-1] +
                                              in3DImageData[i-1][j+1][3] * kernal[xf-1][yf+1] +
                                              in3DImageData[i+1][j][3] * kernal[xf+1][yf] +
                                              in3DImageData[i+1][j-1][3] * kernal[xf+1][yf-1] + 
                                              in3DImageData[i+1][j+1][3] * kernal[xf+1][yf+1]);
                }
            }
        }

        return out3DImageData;
    }

    public int[][][] get3DImageData(WritableImage image) {
        int width = (int) image.getWidth();
        int height = (int) image.getHeight();

        int[][][] threeImageData = new int[width][height][4];//三维信息矩阵

        PixelReader pixelReader = image.getPixelReader();

        for(int i=0;i<width;i++) {
            for(int j=0;j<height;j++) {
                int color = pixelReader.getArgb(i, j);
                int a = (color >> 24) & 0xff;
                int r = (color >> 16) & 0xff;
                int g = (color >> 8) & 0xff;
                int b = color & 0xff;

                threeImageData[i][j][0] = a;
                threeImageData[i][j][1] = r;
                threeImageData[i][j][2] = g;
                threeImageData[i][j][3] = b;
            }
        }

        return threeImageData;
    }

    //使用处理前后的像素数据矩阵计算归一化因子
    public double getRate(int[][][] inData,int[][][] outData) {
        int inPeak = 0;
        int outPeak = 0;
        for(int row=0; row<outData.length; row++) {
            for(int col=0; col<outData[0].length; col++) {
               if(inPeak < inData[row][col][1]) {
                   inPeak = inData[row][col][1];
               }

               if(inPeak < inData[row][col][2]) {
                   inPeak = inData[row][col][2];
               }

               if(inPeak < inData[row][col][3]) {
                   inPeak = inData[row][col][3];
               }

               if(outPeak < outData[row][col][1]) {
                   outPeak = outData[row][col][1];
               }
               if(outPeak < outData[row][col][2]) {
                   outPeak = outData[row][col][2];
               }
               if(outPeak < outData[row][col][3]) {
                   outPeak = outData[row][col][3];
               }
            }
        }
        return (double)inPeak/outPeak;
    }

    //使用归一化因子对矩阵做归一化处理
    public int[][][] makeNormal(int[][][] outData,double peak){
        for(int row=0; row<outData.length; row++) {
            for(int col=0; col<outData[0].length; col++) {
                outData[row][col][1] = (int)(peak * outData[row][col][1]);
                outData[row][col][2] = (int)(peak * outData[row][col][2]);
                outData[row][col][3] = (int)(peak * outData[row][col][3]);
            }
        }
        return outData;
    }
}

效果如下:
这里写图片描述
代码参考博文:http://blog.csdn.net/jia20003/article/details/7234741

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值