/* * HaoRan ImageFilter Classes v0.1 * Copyright (C) 2012 Zhenjun Dai * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation; either version 2.1 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation. */ package com.marshalchen.common.uimodule.ImageFilter; import java.lang.reflect.Array; /** * ��˹ģ��filter * @author daizhj * */ public class GaussianBlurFilter implements IImageFilter{ protected static int Padding = 3; /// <summary> /// The bluriness factor. /// Should be in the range [0, 40]. /// </summary> public float Sigma = 0.75f; float[] ApplyBlur(float[] srcPixels, int width, int height) { float[] destPixels = new float[srcPixels.length]; System.arraycopy(srcPixels, 0, destPixels, 0, srcPixels.length); int w = width + Padding*2; int h = height + Padding*2; // Calculate the coefficients float q = Sigma; float q2 = q * q; float q3 = q2 * q; float b0 = 1.57825f + 2.44413f * q + 1.4281f * q2 + 0.422205f * q3; float b1 = 2.44413f * q + 2.85619f * q2 + 1.26661f * q3; float b2 = -(1.4281f * q2 + 1.26661f * q3); float b3 = 0.422205f * q3; float b = 1.0f - ((b1 + b2 + b3) / b0); // Apply horizontal pass ApplyPass(destPixels, w, h, b0, b1, b2, b3, b); // Transpose the array float[] transposedPixels = new float[destPixels.length]; Transpose(destPixels, transposedPixels, w, h); // Apply vertical pass ApplyPass(transposedPixels, h, w, b0, b1, b2, b3, b); // transpose back Transpose(transposedPixels, destPixels, h, w); return destPixels; } void ApplyPass(float[] pixels, int width, int height, float b0, float b1, float b2, float b3, float b) { float num = 1f / b0; int triplewidth = width * 3; for (int i = 0; i < height; i++) { int steplength = i * triplewidth; for (int j = steplength + 9; j < (steplength + triplewidth); j += 3) { pixels[j] = (b * pixels[j]) + ((((b1 * pixels[j - 3]) + (b2 * pixels[j - 6])) + (b3 * pixels[j - 9])) * num); pixels[j + 1] = (b * pixels[j + 1]) + ((((b1 * pixels[(j + 1) - 3]) + (b2 * pixels[(j + 1) - 6])) + (b3 * pixels[(j + 1) - 9])) * num); pixels[j + 2] = (b * pixels[j + 2]) + ((((b1 * pixels[(j + 2) - 3]) + (b2 * pixels[(j + 2) - 6])) + (b3 * pixels[(j + 2) - 9])) * num); } for (int k = ((steplength + triplewidth) - 9) - 3; k >= steplength; k -= 3){ pixels[k] = (b * pixels[k]) + ((((b1 * pixels[k + 3]) + (b2 * pixels[k + 6])) + (b3 * pixels[k + 9])) * num); pixels[k + 1] = (b * pixels[k + 1]) + ((((b1 * pixels[(k + 1) + 3]) + (b2 * pixels[(k + 1) + 6])) + (b3 * pixels[(k + 1) + 9])) * num); pixels[k + 2] = (b * pixels[k + 2]) + ((((b1 * pixels[(k + 2) + 3]) + (b2 * pixels[(k + 2) + 6])) + (b3 * pixels[(k + 2) + 9])) * num); } } } void Transpose(float[] input, float[] output, int width, int height) { for (int i = 0; i < height; i++){ for (int j = 0; j < width; j++){ int index = (j * height) * 3 + (i * 3); int pos = (i * width) * 3 + (j * 3); output[index] = input[pos]; output[index + 1] = input[pos + 1]; output[index + 2] = input[pos + 2]; } } } float[] ConvertImageWithPadding(Image imageIn, int width, int height) { int newheight = height + Padding*2; int newwidth = width + Padding*2; float[] numArray = new float[(newheight * newwidth) * 3]; int index = 0; int num = 0; for (int i = -3; num < newheight; i++) { int y = i; if (i < 0){ y = 0; } else if (i >= height){ y = height - 1; } int count = 0; int negpadding = -1 * Padding; while (count < newwidth){ int x = negpadding; if (negpadding < 0){ x = 0; } else if (negpadding >= width){ x = width - 1; } numArray[index] = imageIn.getRComponent(x, y) * 0.003921569f; numArray[index + 1] =imageIn.getGComponent(x, y) * 0.003921569f; numArray[index + 2] = imageIn.getBComponent(x, y) * 0.003921569f; count++; negpadding++; index += 3; } num++; } return numArray; } //@Override public Image process(Image imageIn) { int width = imageIn.getWidth(); int height = imageIn.getHeight(); float[] imageArray = ConvertImageWithPadding(imageIn, width, height); imageArray = ApplyBlur(imageArray, width, height); int newwidth = width + Padding*2; for (int i = 0; i < height; i++) { int num = ((i + 3) * newwidth) + 3; for (int j = 0; j < width; j++){ int pos = (num + j) * 3; imageIn.setPixelColor(j, i, (byte) (imageArray[pos] * 255f), (byte) (imageArray[pos + 1] * 255f), (byte) (imageArray[pos + 2] * 255f)); } } return imageIn; } }