001 /* 002 * 003 004 Licensed under the Apache License, Version 2.0 (the "License"); 005 you may not use this file except in compliance with the License. 006 You may obtain a copy of the License at 007 008 http://www.apache.org/licenses/LICENSE-2.0 009 010 Unless required by applicable law or agreed to in writing, software 011 distributed under the License is distributed on an "AS IS" BASIS, 012 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 See the License for the specific language governing permissions and 014 limitations under the License. 015 */ 016 017 package railo.runtime.img.filter;import java.awt.image.BufferedImage; 018 019 import railo.runtime.engine.ThreadLocalPageContext; 020 import railo.runtime.exp.FunctionException; 021 import railo.runtime.exp.PageException; 022 import railo.runtime.img.math.Noise; 023 import railo.runtime.type.KeyImpl; 024 import railo.runtime.type.List; 025 import railo.runtime.type.Struct; 026 027 /** 028 * A filter which distorts an image as if it were underwater. 029 */ 030 public class SwimFilter extends TransformFilter implements DynFiltering { 031 032 private float scale = 32; 033 private float stretch = 1.0f; 034 private float angle = 0.0f; 035 private float amount = 1.0f; 036 private float turbulence = 1.0f; 037 private float time = 0.0f; 038 private float m00 = 1.0f; 039 private float m01 = 0.0f; 040 private float m10 = 0.0f; 041 private float m11 = 1.0f; 042 043 public SwimFilter() { 044 } 045 046 /** 047 * Set the amount of swim. 048 * @param amount the amount of swim 049 * @min-value 0 050 * @max-value 100+ 051 * @see #getAmount 052 */ 053 public void setAmount(float amount) { 054 this.amount = amount; 055 } 056 057 /** 058 * Get the amount of swim. 059 * @return the amount swim 060 * @see #setAmount 061 */ 062 public float getAmount() { 063 return amount; 064 } 065 066 /** 067 * Specifies the scale of the distortion. 068 * @param scale the scale of the distortion. 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 distortion. 079 * @return the scale of the distortion. 080 * @see #setScale 081 */ 082 public float getScale() { 083 return scale; 084 } 085 086 /** 087 * Specifies the stretch factor of the distortion. 088 * @param stretch the stretch factor of the distortion. 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 distortion. 099 * @return the stretch factor of the distortion. 100 * @see #setStretch 101 */ 102 public float getStretch() { 103 return stretch; 104 } 105 106 /** 107 * Specifies the angle of the effect. 108 * @param angle the angle of the effect. 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 effect. 124 * @return the angle of the effect. 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 effect. 144 * @return the turbulence of the effect. 145 * @see #setTurbulence 146 */ 147 public float getTurbulence() { 148 return turbulence; 149 } 150 151 /** 152 * Specifies the time. Use this to animate the effect. 153 * @param time the time. 154 * @angle 155 * @see #getTime 156 */ 157 public void setTime(float time) { 158 this.time = time; 159 } 160 161 /** 162 * Returns the time. 163 * @return the time. 164 * @see #setTime 165 */ 166 public float getTime() { 167 return time; 168 } 169 170 protected void transformInverse(int x, int y, float[] out) { 171 float nx = m00*x + m01*y; 172 float ny = m10*x + m11*y; 173 nx /= scale; 174 ny /= scale * stretch; 175 176 if ( turbulence == 1.0f ) { 177 out[0] = x + amount * Noise.noise3(nx+0.5f, ny, time); 178 out[1] = y + amount * Noise.noise3(nx, ny+0.5f, time); 179 } else { 180 out[0] = x + amount * Noise.turbulence3(nx+0.5f, ny, turbulence, time); 181 out[1] = y + amount * Noise.turbulence3(nx, ny+0.5f, turbulence, time); 182 } 183 } 184 185 public String toString() { 186 return "Distort/Swim..."; 187 } 188 public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=null;//ImageUtil.createBufferedImage(src); 189 Object o; 190 if((o=parameters.removeEL(KeyImpl.init("Amount")))!=null)setAmount(ImageFilterUtil.toFloatValue(o,"Amount")); 191 if((o=parameters.removeEL(KeyImpl.init("Turbulence")))!=null)setTurbulence(ImageFilterUtil.toFloatValue(o,"Turbulence")); 192 if((o=parameters.removeEL(KeyImpl.init("Stretch")))!=null)setStretch(ImageFilterUtil.toFloatValue(o,"Stretch")); 193 if((o=parameters.removeEL(KeyImpl.init("Angle")))!=null)setAngle(ImageFilterUtil.toFloatValue(o,"Angle")); 194 if((o=parameters.removeEL(KeyImpl.init("Time")))!=null)setTime(ImageFilterUtil.toFloatValue(o,"Time")); 195 if((o=parameters.removeEL(KeyImpl.init("Scale")))!=null)setScale(ImageFilterUtil.toFloatValue(o,"Scale")); 196 if((o=parameters.removeEL(KeyImpl.init("EdgeAction")))!=null)setEdgeAction(ImageFilterUtil.toString(o,"EdgeAction")); 197 if((o=parameters.removeEL(KeyImpl.init("Interpolation")))!=null)setInterpolation(ImageFilterUtil.toString(o,"Interpolation")); 198 199 // check for arguments not supported 200 if(parameters.size()>0) { 201 throw new FunctionException(ThreadLocalPageContext.get(), "ImageFilter", 3, "parameters", "the parameter"+(parameters.size()>1?"s":"")+" ["+List.arrayToList(parameters.keysAsString(),", ")+"] "+(parameters.size()>1?"are":"is")+" not allowed, only the following parameters are supported [Amount, Turbulence, Stretch, Angle, Time, Scale, EdgeAction, Interpolation]"); 202 } 203 204 return filter(src, dst); 205 } 206 }