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.image.BufferedImage;
036
037import lucee.runtime.engine.ThreadLocalPageContext;
038import lucee.runtime.exp.FunctionException;
039import lucee.runtime.exp.PageException;
040import lucee.runtime.img.ImageUtil;
041import lucee.runtime.type.KeyImpl;
042import lucee.runtime.type.Struct;
043import lucee.runtime.type.util.CollectionUtil;
044
045public class ErodeAlphaFilter extends PointFilter  implements DynFiltering {
046
047        private float threshold;
048        private float softness = 0;
049    protected float radius = 5;
050        private float lowerThreshold;
051        private float upperThreshold;
052
053        public ErodeAlphaFilter() {
054                this( 3, 0.75f, 0 );
055        }
056
057        public ErodeAlphaFilter( float radius, float threshold, float softness ) {
058                this.radius = radius;
059                this.threshold = threshold;
060                this.softness = softness;
061        }
062
063        public void setRadius(float radius) {
064                this.radius = radius;
065        }
066        
067        public float getRadius() {
068                return radius;
069        }
070
071        public void setThreshold(float threshold) {
072                this.threshold = threshold;
073        }
074        
075        public float getThreshold() {
076                return threshold;
077        }
078        
079        public void setSoftness(float softness) {
080                this.softness = softness;
081        }
082
083        public float getSoftness() {
084                return softness;
085        }
086
087    public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
088        dst = new GaussianFilter( (int)radius ).filter( src, (BufferedImage)null );
089        lowerThreshold = 255*(threshold - softness*0.5f);
090        upperThreshold = 255*(threshold + softness*0.5f);
091                return super.filter(dst, dst);
092        }
093
094        public int filterRGB(int x, int y, int rgb) {
095                int a = (rgb >> 24) & 0xff;
096                //int r = (rgb >> 16) & 0xff;
097                //int g = (rgb >> 8) & 0xff;
098                //int b = rgb & 0xff;
099                if ( a == 255 )
100            return 0xffffffff;
101        float f = ImageMath.smoothStep(lowerThreshold, upperThreshold, a);
102        a = (int)(f * 255);
103        if ( a < 0 )
104            a = 0;
105        else if ( a > 255 )
106            a = 255;
107        return (a << 24) | 0xffffff;
108        }
109
110        public String toString() {
111                return "Alpha/Erode...";
112        }
113        public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src);
114                Object o;
115                if((o=parameters.removeEL(KeyImpl.init("Radius")))!=null)setRadius(ImageFilterUtil.toFloatValue(o,"Radius"));
116                if((o=parameters.removeEL(KeyImpl.init("Softness")))!=null)setSoftness(ImageFilterUtil.toFloatValue(o,"Softness"));
117                if((o=parameters.removeEL(KeyImpl.init("Threshold")))!=null)setThreshold(ImageFilterUtil.toFloatValue(o,"Threshold"));
118                if((o=parameters.removeEL(KeyImpl.init("Dimensions")))!=null){
119                        int[] dim=ImageFilterUtil.toDimensions(o,"Dimensions");
120                        setDimensions(dim[0],dim[1]);
121                }
122
123                // check for arguments not supported
124                if(parameters.size()>0) {
125                        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 [Radius, Softness, Threshold, Dimensions]");
126                }
127
128                return filter(src, dst);
129        }
130}