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.image.BufferedImage;
018    import java.util.Random;
019    
020    import railo.runtime.engine.ThreadLocalPageContext;
021    import railo.runtime.exp.FunctionException;
022    import railo.runtime.exp.PageException;
023    import railo.runtime.img.ImageUtil;
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 "dissolves" an image by thresholding the alpha channel with random numbers.
030     */
031    public class DissolveFilter extends PointFilter  implements DynFiltering {
032            
033            private float density = 1;
034            private float softness = 0;
035            private float minDensity, maxDensity;
036            private Random randomNumbers;
037            
038            public DissolveFilter() {
039            }
040    
041            /**
042             * Set the density of the image in the range 0..1.
043             * @param density the density
044         * @min-value 0
045         * @max-value 1
046         * @see #getDensity
047             */
048            public void setDensity( float density ) {
049                    this.density = density;
050            }
051            
052            /**
053             * Get the density of the image.
054             * @return the density
055         * @see #setDensity
056             */
057            public float getDensity() {
058                    return density;
059            }
060            
061            /**
062             * Set the softness of the dissolve in the range 0..1.
063             * @param softness the softness
064         * @min-value 0
065         * @max-value 1
066         * @see #getSoftness
067             */
068            public void setSoftness( float softness ) {
069                    this.softness = softness;
070            }
071            
072            /**
073             * Get the softness of the dissolve.
074             * @return the softness
075         * @see #setSoftness
076             */
077            public float getSoftness() {
078                    return softness;
079            }
080            
081        public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
082                    float d = (1-density) * (1+softness);
083                    minDensity = d-softness;
084                    maxDensity = d;
085                    randomNumbers = new Random( 0 );
086                    return super.filter( src, dst );
087            }
088            
089            public int filterRGB(int x, int y, int rgb) {
090                    int a = (rgb >> 24) & 0xff;
091                    float v = randomNumbers.nextFloat();
092                    float f = ImageMath.smoothStep( minDensity, maxDensity, v );
093                    return ((int)(a * f) << 24) | rgb & 0x00ffffff;
094            }
095    
096            public String toString() {
097                    return "Stylize/Dissolve...";
098            }
099            public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src);
100                    Object o;
101                    if((o=parameters.removeEL(KeyImpl.init("Density")))!=null)setDensity(ImageFilterUtil.toFloatValue(o,"Density"));
102                    if((o=parameters.removeEL(KeyImpl.init("Softness")))!=null)setSoftness(ImageFilterUtil.toFloatValue(o,"Softness"));
103                    if((o=parameters.removeEL(KeyImpl.init("Dimensions")))!=null){
104                            int[] dim=ImageFilterUtil.toDimensions(o,"Dimensions");
105                            setDimensions(dim[0],dim[1]);
106                    }
107    
108                    // check for arguments not supported
109                    if(parameters.size()>0) {
110                            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 [Density, Softness, Dimensions]");
111                    }
112    
113                    return filter(src, dst);
114            }
115    }