001/* 002Copyright 2006 Jerry Huxtable 003 004Licensed under the Apache License, Version 2.0 (the "License"); 005you may not use this file except in compliance with the License. 006You may obtain a copy of the License at 007 008 http://www.apache.org/licenses/LICENSE-2.0 009 010Unless required by applicable law or agreed to in writing, software 011distributed under the License is distributed on an "AS IS" BASIS, 012WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013See the License for the specific language governing permissions and 014limitations under the License. 015*/ 016 017package com.jhlabs.image; 018 019import java.awt.*; 020import java.awt.image.*; 021 022/** 023 * A filter which performs reduces noise by looking at each pixel's 8 neighbours, and if it's a minimum or maximum, 024 * replacing it by the next minimum or maximum of the neighbours. 025 */ 026public class ReduceNoiseFilter extends WholeImageFilter { 027 028 public ReduceNoiseFilter() { 029 } 030 031 private int smooth(int[] v) { 032 int minindex = 0, maxindex = 0, min = Integer.MAX_VALUE, max = Integer.MIN_VALUE; 033 034 for (int i = 0; i < 9; i++) { 035 if ( i != 4 ) { 036 if (v[i] < min) { 037 min = v[i]; 038 minindex = i; 039 } 040 if (v[i] > max) { 041 max = v[i]; 042 maxindex = i; 043 } 044 } 045 } 046 if ( v[4] < min ) 047 return v[minindex]; 048 if ( v[4] > max ) 049 return v[maxindex]; 050 return v[4]; 051 } 052 053 protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) { 054 int index = 0; 055 int[] r = new int[9]; 056 int[] g = new int[9]; 057 int[] b = new int[9]; 058 int[] outPixels = new int[width * height]; 059 060 for (int y = 0; y < height; y++) { 061 for (int x = 0; x < width; x++) { 062 int k = 0; 063 int irgb = inPixels[index]; 064 int ir = (irgb >> 16) & 0xff; 065 int ig = (irgb >> 8) & 0xff; 066 int ib = irgb & 0xff; 067 for (int dy = -1; dy <= 1; dy++) { 068 int iy = y+dy; 069 if (0 <= iy && iy < height) { 070 int ioffset = iy*width; 071 for (int dx = -1; dx <= 1; dx++) { 072 int ix = x+dx; 073 if (0 <= ix && ix < width) { 074 int rgb = inPixels[ioffset+ix]; 075 r[k] = (rgb >> 16) & 0xff; 076 g[k] = (rgb >> 8) & 0xff; 077 b[k] = rgb & 0xff; 078 } else { 079 r[k] = ir; 080 g[k] = ig; 081 b[k] = ib; 082 } 083 k++; 084 } 085 } else { 086 for (int dx = -1; dx <= 1; dx++) { 087 r[k] = ir; 088 g[k] = ig; 089 b[k] = ib; 090 k++; 091 } 092 } 093 } 094 outPixels[index] = (inPixels[index] & 0xff000000) | (smooth(r) << 16) | (smooth(g) << 8) | smooth(b); 095 index++; 096 } 097 } 098 return outPixels; 099 } 100 101 public String toString() { 102 return "Blur/Smooth"; 103 } 104 105} 106