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.Point; 018 import java.awt.Rectangle; 019 import java.awt.image.BufferedImage; 020 021 import railo.runtime.engine.ThreadLocalPageContext; 022 import railo.runtime.exp.FunctionException; 023 import railo.runtime.exp.PageException; 024 import railo.runtime.type.KeyImpl; 025 import railo.runtime.type.Struct; 026 import railo.runtime.type.util.CollectionUtil; 027 028 /** 029 * A filter which rotates an image. These days this is easier done with Java2D, but this filter remains. 030 */ 031 public class RotateFilter extends TransformFilter implements DynFiltering { 032 033 private float angle; 034 private float cos, sin; 035 private boolean resize = true; 036 037 /** 038 * Construct a RotateFilter. 039 */ 040 public RotateFilter() { 041 this(ImageMath.PI); 042 } 043 044 /** 045 * Construct a RotateFilter. 046 * @param angle the angle to rotate 047 */ 048 public RotateFilter(float angle) { 049 this(angle, true); 050 } 051 052 /** 053 * Construct a RotateFilter. 054 * @param angle the angle to rotate 055 * @param resize true if the output image should be resized 056 */ 057 public RotateFilter(float angle, boolean resize) { 058 setAngle(angle); 059 this.resize = resize; 060 } 061 062 /** 063 * Specifies the angle of rotation. 064 * @param angle the angle of rotation. 065 * @angle 066 * @see #getAngle 067 */ 068 public void setAngle(float angle) { 069 this.angle = angle; 070 cos = (float)Math.cos(this.angle); 071 sin = (float)Math.sin(this.angle); 072 } 073 074 /** 075 * Returns the angle of rotation. 076 * @return the angle of rotation. 077 * @see #setAngle 078 */ 079 public float getAngle() { 080 return angle; 081 } 082 083 protected void transformSpace(Rectangle rect) { 084 if (resize) { 085 Point out = new Point(0, 0); 086 int minx = Integer.MAX_VALUE; 087 int miny = Integer.MAX_VALUE; 088 int maxx = Integer.MIN_VALUE; 089 int maxy = Integer.MIN_VALUE; 090 int w = rect.width; 091 int h = rect.height; 092 int x = rect.x; 093 int y = rect.y; 094 095 for (int i = 0; i < 4; i++) { 096 switch (i) { 097 case 0: transform(x, y, out); break; 098 case 1: transform(x + w, y, out); break; 099 case 2: transform(x, y + h, out); break; 100 case 3: transform(x + w, y + h, out); break; 101 } 102 minx = Math.min(minx, out.x); 103 miny = Math.min(miny, out.y); 104 maxx = Math.max(maxx, out.x); 105 maxy = Math.max(maxy, out.y); 106 } 107 108 rect.x = minx; 109 rect.y = miny; 110 rect.width = maxx - minx; 111 rect.height = maxy - miny; 112 } 113 } 114 115 116 117 private void transform(int x, int y, Point out) { 118 out.x = (int)((x * cos) + (y * sin)); 119 out.y = (int)((y * cos) - (x * sin)); 120 } 121 122 protected void transformInverse(int x, int y, float[] out) { 123 out[0] = (x * cos) - (y * sin); 124 out[1] = (y * cos) + (x * sin); 125 } 126 127 public String toString() { 128 return "Rotate "+(int)(angle * 180 / Math.PI); 129 } 130 131 public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException { 132 //BufferedImage dst=ImageUtil.createBufferedImage(src,src.getWidth()+400,src.getHeight()+400); 133 Object o; 134 if((o=parameters.removeEL(KeyImpl.init("Angle")))!=null)setAngle(ImageFilterUtil.toFloatValue(o,"Angle")); 135 if((o=parameters.removeEL(KeyImpl.init("EdgeAction")))!=null)setEdgeAction(ImageFilterUtil.toString(o,"EdgeAction")); 136 if((o=parameters.removeEL(KeyImpl.init("Interpolation")))!=null)setInterpolation(ImageFilterUtil.toString(o,"Interpolation")); 137 138 // check for arguments not supported 139 if(parameters.size()>0) { 140 throw new FunctionException(ThreadLocalPageContext.get(), "ImageFilter", 3, "parameters", "the parameter"+(parameters.size()>1?"s":"")+" ["+CollectionUtil.getKeyList(parameters,", ")+"] "+(parameters.size()>1?"are":"is")+" not allowed, only the following parameters are supported [Angle, EdgeAction, Interpolation]"); 141 } 142 143 144 145 //Rectangle rect = new Rectangle(0, 0, src.getWidth(), src.getHeight()); 146 //transformSpace(rect); 147 BufferedImage dst=null;//ImageUtil.createBufferedImage(src,rect.width,rect.height); 148 149 return filter(src, dst); 150 } 151 }