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.Graphics2D;
036import java.awt.geom.AffineTransform;
037import java.awt.image.BufferedImage;
038
039import lucee.runtime.engine.ThreadLocalPageContext;
040import lucee.runtime.exp.FunctionException;
041import lucee.runtime.exp.PageException;
042import lucee.runtime.img.ImageUtil;
043import lucee.runtime.type.KeyImpl;
044import lucee.runtime.type.Struct;
045import lucee.runtime.type.util.CollectionUtil;
046
047/**
048 * A filter which crops an image to a given rectangle.
049 */
050public class CropFilter extends AbstractBufferedImageOp  implements DynFiltering {
051
052        private int x;
053        private int y;
054        private int width;
055        private int height;
056
057    /**
058     * Construct a CropFilter.
059     */
060        public CropFilter() {
061                this(0, 0, 32, 32);
062        }
063
064    /**
065     * Construct a CropFilter.
066     * @param x the left edge of the crop rectangle
067     * @param y the top edge of the crop rectangle
068     * @param width the width of the crop rectangle
069     * @param height the height of the crop rectangle
070     */
071        public CropFilter(int x, int y, int width, int height) {
072                this.x = x;
073                this.y = y;
074                this.width = width;
075                this.height = height;
076        }
077
078    /**
079     * Set the left edge of the crop rectangle.
080     * @param x the left edge of the crop rectangle
081     * @see #getX
082     */
083        public void setX(int x) {
084                this.x = x;
085        }
086
087    /**
088     * Get the left edge of the crop rectangle.
089     * @return the left edge of the crop rectangle
090     * @see #setX
091     */
092        public int getX() {
093                return x;
094        }
095
096    /**
097     * Set the top edge of the crop rectangle.
098     * @param y the top edge of the crop rectangle
099     * @see #getY
100     */
101        public void setY(int y) {
102                this.y = y;
103        }
104
105    /**
106     * Get the top edge of the crop rectangle.
107     * @return the top edge of the crop rectangle
108     * @see #setY
109     */
110        public int getY() {
111                return y;
112        }
113
114    /**
115     * Set the width of the crop rectangle.
116     * @param width the width of the crop rectangle
117     * @see #getWidth
118     */
119        public void setWidth(int width) {
120                this.width = width;
121        }
122
123    /**
124     * Get the width of the crop rectangle.
125     * @return the width of the crop rectangle
126     * @see #setWidth
127     */
128        public int getWidth() {
129                return width;
130        }
131
132    /**
133     * Set the height of the crop rectangle.
134     * @param height the height of the crop rectangle
135     * @see #getHeight
136     */
137        public void setHeight(int height) {
138                this.height = height;
139        }
140
141    /**
142     * Get the height of the crop rectangle.
143     * @return the height of the crop rectangle
144     * @see #setHeight
145     */
146        public int getHeight() {
147                return height;
148        }
149
150    public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
151        
152        int w = src.getWidth();
153        int h = src.getHeight();
154
155        if(x<0)x=0;
156        if(y<0)y=0;
157        if(x>w)x=w;
158        if(y>h)y=h;
159        
160        
161                dst=ImageUtil.createBufferedImage(src,width,height);
162                
163
164        
165
166                Graphics2D g = dst.createGraphics();
167                g.drawRenderedImage( src, AffineTransform.getTranslateInstance(-x, -y) );
168                g.dispose();
169
170        return dst;
171    }
172
173        public String toString() {
174                return "Distort/Crop";
175        }
176        public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {
177                Object o;
178                if((o=parameters.removeEL(KeyImpl.init("X")))!=null)setX(ImageFilterUtil.toIntValue(o,"X"));
179                if((o=parameters.removeEL(KeyImpl.init("Y")))!=null)setY(ImageFilterUtil.toIntValue(o,"Y"));
180                if((o=parameters.removeEL(KeyImpl.init("Width")))!=null)setWidth(ImageFilterUtil.toIntValue(o,"Width"));
181                if((o=parameters.removeEL(KeyImpl.init("Height")))!=null)setHeight(ImageFilterUtil.toIntValue(o,"Height"));
182
183                // check for arguments not supported
184                if(parameters.size()>0) {
185                        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 [X, Y, Width, Height]");
186                }
187
188                return filter(src, (BufferedImage)null);
189        }
190}