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.AlphaComposite; 018 import java.awt.Color; 019 import java.awt.GradientPaint; 020 import java.awt.Graphics2D; 021 import java.awt.Shape; 022 import java.awt.image.BufferedImage; 023 024 import railo.runtime.engine.ThreadLocalPageContext; 025 import railo.runtime.exp.FunctionException; 026 import railo.runtime.exp.PageException; 027 import railo.runtime.img.ImageUtil; 028 import railo.runtime.type.KeyImpl; 029 import railo.runtime.type.Struct; 030 import railo.runtime.type.util.CollectionUtil; 031 032 public class MirrorFilter extends AbstractBufferedImageOp implements DynFiltering { 033 private float opacity = 1.0f; 034 private float centreY = 0.5f; 035 private float distance; 036 private float angle; 037 private float rotation; 038 private float gap; 039 040 public MirrorFilter() { 041 } 042 043 /** 044 * Specifies the angle of the mirror. 045 * @param angle the angle of the mirror. 046 * @angle 047 * @see #getAngle 048 */ 049 public void setAngle( float angle ) { 050 this.angle = angle; 051 } 052 053 /** 054 * Returns the angle of the mirror. 055 * @return the angle of the mirror. 056 * @see #setAngle 057 */ 058 public float getAngle() { 059 return angle; 060 } 061 062 public void setDistance( float distance ) { 063 this.distance = distance; 064 } 065 066 public float getDistance() { 067 return distance; 068 } 069 070 public void setRotation( float rotation ) { 071 this.rotation = rotation; 072 } 073 074 public float getRotation() { 075 return rotation; 076 } 077 078 public void setGap( float gap ) { 079 this.gap = gap; 080 } 081 082 public float getGap() { 083 return gap; 084 } 085 086 /** 087 * Set the opacity of the reflection. 088 * @param opacity the opacity. 089 * @see #getOpacity 090 */ 091 public void setOpacity( float opacity ) { 092 this.opacity = opacity; 093 } 094 095 /** 096 * Get the opacity of the reflection. 097 * @return the opacity. 098 * @see #setOpacity 099 */ 100 public float getOpacity() { 101 return opacity; 102 } 103 104 public void setCentreY( float centreY ) { 105 this.centreY = centreY; 106 } 107 108 public float getCentreY() { 109 return centreY; 110 } 111 112 public BufferedImage filter( BufferedImage src, BufferedImage dst ) { 113 if ( dst == null ) 114 dst = createCompatibleDestImage( src, null ); 115 //BufferedImage tsrc = src; 116 Shape clip; 117 int width = src.getWidth(); 118 int height = src.getHeight(); 119 int h = (int)(centreY * height); 120 int d = (int)(gap * height); 121 122 Graphics2D g = dst.createGraphics(); 123 clip = g.getClip(); 124 g.clipRect( 0, 0, width, h ); 125 g.drawRenderedImage( src, null ); 126 g.setClip( clip ); 127 g.clipRect( 0, h+d, width, height-h-d ); 128 g.translate( 0, 2*h+d ); 129 g.scale( 1, -1 ); 130 g.drawRenderedImage( src, null ); 131 g.setPaint( new GradientPaint( 0, 0, new Color( 1.0f, 0.0f, 0.0f, 0.0f ), 0, h, new Color( 0.0f, 1.0f, 0.0f, opacity ) ) ); 132 g.setComposite( AlphaComposite.getInstance( AlphaComposite.DST_IN ) ); 133 g.fillRect( 0, 0, width, h ); 134 g.setClip( clip ); 135 g.dispose(); 136 137 return dst; 138 } 139 140 public String toString() { 141 return "Effects/Mirror..."; 142 } 143 public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src); 144 Object o; 145 if((o=parameters.removeEL(KeyImpl.init("Angle")))!=null)setAngle(ImageFilterUtil.toFloatValue(o,"Angle")); 146 if((o=parameters.removeEL(KeyImpl.init("CentreY")))!=null)setCentreY(ImageFilterUtil.toFloatValue(o,"CentreY")); 147 if((o=parameters.removeEL(KeyImpl.init("Distance")))!=null)setDistance(ImageFilterUtil.toFloatValue(o,"Distance")); 148 if((o=parameters.removeEL(KeyImpl.init("Rotation")))!=null)setRotation(ImageFilterUtil.toFloatValue(o,"Rotation")); 149 if((o=parameters.removeEL(KeyImpl.init("Gap")))!=null)setGap(ImageFilterUtil.toFloatValue(o,"Gap")); 150 if((o=parameters.removeEL(KeyImpl.init("Opacity")))!=null)setOpacity(ImageFilterUtil.toFloatValue(o,"Opacity")); 151 152 // check for arguments not supported 153 if(parameters.size()>0) { 154 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, CentreY, Distance, Rotation, Gap, Opacity]"); 155 } 156 157 return filter(src, dst); 158 } 159 }