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.image.*; 020import com.jhlabs.math.*; 021 022/** 023 * A filter which produces a simulated wood texture. This is a bit of a hack, but might be usefult to some people. 024 */ 025public class WoodFilter extends PointFilter { 026 027 private float scale = 200; 028 private float stretch = 10.0f; 029 private float angle = (float)Math.PI/2; 030 private float rings = 0.5f; 031 private float turbulence = 0.0f; 032 private float fibres = 0.5f; 033 private float gain = 0.8f; 034 private float m00 = 1.0f; 035 private float m01 = 0.0f; 036 private float m10 = 0.0f; 037 private float m11 = 1.0f; 038 private Colormap colormap = new LinearColormap( 0xffe5c494, 0xff987b51 ); 039 040 /** 041 * Construct a WoodFilter. 042 */ 043 public WoodFilter() { 044 } 045 046 /** 047 * Specifies the rings value. 048 * @param rings the rings value. 049 * @min-value 0 050 * @max-value 1 051 * @see #getRings 052 */ 053 public void setRings(float rings) { 054 this.rings = rings; 055 } 056 057 /** 058 * Returns the rings value. 059 * @return the rings value. 060 * @see #setRings 061 */ 062 public float getRings() { 063 return rings; 064 } 065 066 /** 067 * Specifies the scale of the texture. 068 * @param scale the scale of the texture. 069 * @min-value 1 070 * @max-value 300+ 071 * @see #getScale 072 */ 073 public void setScale(float scale) { 074 this.scale = scale; 075 } 076 077 /** 078 * Returns the scale of the texture. 079 * @return the scale of the texture. 080 * @see #setScale 081 */ 082 public float getScale() { 083 return scale; 084 } 085 086 /** 087 * Specifies the stretch factor of the texture. 088 * @param stretch the stretch factor of the texture. 089 * @min-value 1 090 * @max-value 50+ 091 * @see #getStretch 092 */ 093 public void setStretch(float stretch) { 094 this.stretch = stretch; 095 } 096 097 /** 098 * Returns the stretch factor of the texture. 099 * @return the stretch factor of the texture. 100 * @see #setStretch 101 */ 102 public float getStretch() { 103 return stretch; 104 } 105 106 /** 107 * Specifies the angle of the texture. 108 * @param angle the angle of the texture. 109 * @angle 110 * @see #getAngle 111 */ 112 public void setAngle(float angle) { 113 this.angle = angle; 114 float cos = (float)Math.cos(angle); 115 float sin = (float)Math.sin(angle); 116 m00 = cos; 117 m01 = sin; 118 m10 = -sin; 119 m11 = cos; 120 } 121 122 /** 123 * Returns the angle of the texture. 124 * @return the angle of the texture. 125 * @see #setAngle 126 */ 127 public float getAngle() { 128 return angle; 129 } 130 131 /** 132 * Specifies the turbulence of the texture. 133 * @param turbulence the turbulence of the texture. 134 * @min-value 0 135 * @max-value 1 136 * @see #getTurbulence 137 */ 138 public void setTurbulence(float turbulence) { 139 this.turbulence = turbulence; 140 } 141 142 /** 143 * Returns the turbulence of the texture. 144 * @return the turbulence of the texture. 145 * @see #setTurbulence 146 */ 147 public float getTurbulence() { 148 return turbulence; 149 } 150 151 /** 152 * Specifies the amount of fibres in the texture. 153 * @param fibres the amount of fibres in the texture. 154 * @min-value 0 155 * @max-value 1 156 * @see #getFibres 157 */ 158 public void setFibres(float fibres) { 159 this.fibres = fibres; 160 } 161 162 /** 163 * Returns the amount of fibres in the texture. 164 * @return the amount of fibres in the texture. 165 * @see #setFibres 166 */ 167 public float getFibres() { 168 return fibres; 169 } 170 171 /** 172 * Specifies the gain of the texture. 173 * @param gain the gain of the texture. 174 * @min-value 0 175 * @max-value 1 176 * @see #getGain 177 */ 178 public void setGain(float gain) { 179 this.gain = gain; 180 } 181 182 /** 183 * Returns the gain of the texture. 184 * @return the gain of the texture. 185 * @see #setGain 186 */ 187 public float getGain() { 188 return gain; 189 } 190 191 /** 192 * Set the colormap to be used for the filter. 193 * @param colormap the colormap 194 * @see #getColormap 195 */ 196 public void setColormap(Colormap colormap) { 197 this.colormap = colormap; 198 } 199 200 /** 201 * Get the colormap to be used for the filter. 202 * @return the colormap 203 * @see #setColormap 204 */ 205 public Colormap getColormap() { 206 return colormap; 207 } 208 209 public int filterRGB(int x, int y, int rgb) { 210 float nx = m00*x + m01*y; 211 float ny = m10*x + m11*y; 212 nx /= scale; 213 ny /= scale * stretch; 214 float f = Noise.noise2(nx, ny); 215 f += 0.1f*turbulence * Noise.noise2(nx*0.05f, ny*20); 216 f = (f * 0.5f) + 0.5f; 217 218 f *= rings*50; 219 f = f-(int)f; 220 f *= 1-ImageMath.smoothStep(gain, 1.0f, f); 221 222 f += fibres*Noise.noise2(nx*scale, ny*50); 223 224 int a = rgb & 0xff000000; 225 int v; 226 if (colormap != null) 227 v = colormap.getColor(f); 228 else { 229 v = PixelUtils.clamp((int)(f*255)); 230 int r = v << 16; 231 int g = v << 8; 232 int b = v; 233 v = a|r|g|b; 234 } 235 236 return v; 237 } 238 239 public String toString() { 240 return "Texture/Wood..."; 241 } 242 243}