001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019/* 020* 021 022Licensed under the Apache License, Version 2.0 (the "License"); 023you may not use this file except in compliance with the License. 024You may obtain a copy of the License at 025 026 http://www.apache.org/licenses/LICENSE-2.0 027 028Unless required by applicable law or agreed to in writing, software 029distributed under the License is distributed on an "AS IS" BASIS, 030WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 031See the License for the specific language governing permissions and 032limitations under the License. 033*/ 034 035package lucee.runtime.img.filter;import java.awt.AlphaComposite; 036import java.awt.Color; 037import java.awt.GradientPaint; 038import java.awt.Graphics2D; 039import java.awt.Shape; 040import java.awt.image.BufferedImage; 041 042import lucee.runtime.engine.ThreadLocalPageContext; 043import lucee.runtime.exp.FunctionException; 044import lucee.runtime.exp.PageException; 045import lucee.runtime.img.ImageUtil; 046import lucee.runtime.type.KeyImpl; 047import lucee.runtime.type.Struct; 048import lucee.runtime.type.util.CollectionUtil; 049 050public class MirrorFilter extends AbstractBufferedImageOp implements DynFiltering { 051 private float opacity = 1.0f; 052 private float centreY = 0.5f; 053 private float distance; 054 private float angle; 055 private float rotation; 056 private float gap; 057 058 public MirrorFilter() { 059 } 060 061 /** 062 * Specifies the angle of the mirror. 063 * @param angle the angle of the mirror. 064 * @angle 065 * @see #getAngle 066 */ 067 public void setAngle( float angle ) { 068 this.angle = angle; 069 } 070 071 /** 072 * Returns the angle of the mirror. 073 * @return the angle of the mirror. 074 * @see #setAngle 075 */ 076 public float getAngle() { 077 return angle; 078 } 079 080 public void setDistance( float distance ) { 081 this.distance = distance; 082 } 083 084 public float getDistance() { 085 return distance; 086 } 087 088 public void setRotation( float rotation ) { 089 this.rotation = rotation; 090 } 091 092 public float getRotation() { 093 return rotation; 094 } 095 096 public void setGap( float gap ) { 097 this.gap = gap; 098 } 099 100 public float getGap() { 101 return gap; 102 } 103 104 /** 105 * Set the opacity of the reflection. 106 * @param opacity the opacity. 107 * @see #getOpacity 108 */ 109 public void setOpacity( float opacity ) { 110 this.opacity = opacity; 111 } 112 113 /** 114 * Get the opacity of the reflection. 115 * @return the opacity. 116 * @see #setOpacity 117 */ 118 public float getOpacity() { 119 return opacity; 120 } 121 122 public void setCentreY( float centreY ) { 123 this.centreY = centreY; 124 } 125 126 public float getCentreY() { 127 return centreY; 128 } 129 130 public BufferedImage filter( BufferedImage src, BufferedImage dst ) { 131 if ( dst == null ) 132 dst = createCompatibleDestImage( src, null ); 133 //BufferedImage tsrc = src; 134 Shape clip; 135 int width = src.getWidth(); 136 int height = src.getHeight(); 137 int h = (int)(centreY * height); 138 int d = (int)(gap * height); 139 140 Graphics2D g = dst.createGraphics(); 141 clip = g.getClip(); 142 g.clipRect( 0, 0, width, h ); 143 g.drawRenderedImage( src, null ); 144 g.setClip( clip ); 145 g.clipRect( 0, h+d, width, height-h-d ); 146 g.translate( 0, 2*h+d ); 147 g.scale( 1, -1 ); 148 g.drawRenderedImage( src, null ); 149 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 ) ) ); 150 g.setComposite( AlphaComposite.getInstance( AlphaComposite.DST_IN ) ); 151 g.fillRect( 0, 0, width, h ); 152 g.setClip( clip ); 153 g.dispose(); 154 155 return dst; 156 } 157 158 public String toString() { 159 return "Effects/Mirror..."; 160 } 161 public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src); 162 Object o; 163 if((o=parameters.removeEL(KeyImpl.init("Angle")))!=null)setAngle(ImageFilterUtil.toFloatValue(o,"Angle")); 164 if((o=parameters.removeEL(KeyImpl.init("CentreY")))!=null)setCentreY(ImageFilterUtil.toFloatValue(o,"CentreY")); 165 if((o=parameters.removeEL(KeyImpl.init("Distance")))!=null)setDistance(ImageFilterUtil.toFloatValue(o,"Distance")); 166 if((o=parameters.removeEL(KeyImpl.init("Rotation")))!=null)setRotation(ImageFilterUtil.toFloatValue(o,"Rotation")); 167 if((o=parameters.removeEL(KeyImpl.init("Gap")))!=null)setGap(ImageFilterUtil.toFloatValue(o,"Gap")); 168 if((o=parameters.removeEL(KeyImpl.init("Opacity")))!=null)setOpacity(ImageFilterUtil.toFloatValue(o,"Opacity")); 169 170 // check for arguments not supported 171 if(parameters.size()>0) { 172 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]"); 173 } 174 175 return filter(src, dst); 176 } 177}