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.Color;
018    import java.awt.image.BufferedImage;
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     * A filter which can be used to produce wipes by transferring the luma of a Destination image into the alpha channel of the source.
029     */
030    public class ChromaKeyFilter extends AbstractBufferedImageOp  implements DynFiltering {
031            
032            private float hTolerance = 0;
033            private float sTolerance = 0;
034            private float bTolerance = 0;
035            private int color;
036    
037            public ChromaKeyFilter() {
038            }
039    
040            /**
041             * Set the tolerance of the image in the range 0..1.
042             * *arg tolerance The tolerance
043             */
044            public void setHTolerance( float hTolerance ) {
045                    this.hTolerance = hTolerance;
046            }
047            
048            public float getHTolerance() {
049                    return hTolerance;
050            }
051            
052            public void setSTolerance( float sTolerance ) {
053                    this.sTolerance = sTolerance;
054            }
055            
056            public float getSTolerance() {
057                    return sTolerance;
058            }
059            
060            public void setBTolerance( float bTolerance ) {
061                    this.bTolerance = bTolerance;
062            }
063            
064            public float getBTolerance() {
065                    return bTolerance;
066            }
067            
068            public void setColor( int color ) {
069                    this.color = color;
070            }
071            
072            public int getColor() {
073                    return color;
074            }
075                    
076        public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
077            int width = src.getWidth();
078            int height = src.getHeight();
079                    //int type = src.getType();
080                    //WritableRaster srcRaster = 
081            src.getRaster();
082    
083            if ( dst == null )
084                dst = createCompatibleDestImage( src, null );
085                    //WritableRaster dstRaster = 
086            dst.getRaster();
087    
088                    float[] hsb1 = null;
089                    float[] hsb2 = null;
090                    int rgb2 = color;
091                    int r2 = (rgb2 >> 16) & 0xff;
092                    int g2 = (rgb2 >> 8) & 0xff;
093                    int b2 = rgb2 & 0xff;
094                    hsb2 = Color.RGBtoHSB( r2, b2, g2, hsb2 );
095                    int[] inPixels = null;
096                    for ( int y = 0; y < height; y++ ) {
097                            inPixels = getRGB( src, 0, y, width, 1, inPixels );
098                            for ( int x = 0; x < width; x++ ) {
099                                    int rgb1 = inPixels[x];
100    
101                                    int r1 = (rgb1 >> 16) & 0xff;
102                                    int g1 = (rgb1 >> 8) & 0xff;
103                                    int b1 = rgb1 & 0xff;
104                                    hsb1 = Color.RGBtoHSB( r1, b1, g1, hsb1 );
105    //                    int tolerance = (int)(255*tolerance);
106    //                    return Math.abs(r1-r2) <= tolerance && Math.abs(g1-g2) <= tolerance && Math.abs(b1-b2) <= tolerance;
107    
108    //                   if ( PixelUtils.nearColors( in, clean, (int)(255*tolerance) ) )
109                                    if ( Math.abs( hsb1[0] - hsb2[0] ) < hTolerance && Math.abs( hsb1[1] - hsb2[1] ) < sTolerance && Math.abs( hsb1[2] - hsb2[2] ) < bTolerance )
110                                            inPixels[x] = rgb1 & 0xffffff;
111                                    else
112                                            inPixels[x] = rgb1;
113                            }
114                            setRGB( dst, 0, y, width, 1, inPixels );
115                    }
116    
117            return dst;
118        }
119    
120            public String toString() {
121                    return "Keying/Chroma Key...";
122            }
123            public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src);
124                    Object o;
125                    if((o=parameters.removeEL(KeyImpl.init("HTolerance")))!=null)setHTolerance(ImageFilterUtil.toFloatValue(o,"HTolerance"));
126                    if((o=parameters.removeEL(KeyImpl.init("STolerance")))!=null)setSTolerance(ImageFilterUtil.toFloatValue(o,"STolerance"));
127                    if((o=parameters.removeEL(KeyImpl.init("BTolerance")))!=null)setBTolerance(ImageFilterUtil.toFloatValue(o,"BTolerance"));
128                    if((o=parameters.removeEL(KeyImpl.init("Color")))!=null)setColor(ImageFilterUtil.toIntValue(o,"Color"));
129    
130                    // check for arguments not supported
131                    if(parameters.size()>0) {
132                            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 [HTolerance, STolerance, BTolerance, Color]");
133                    }
134    
135                    return filter(src, dst);
136            }
137    }