代码如下:
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