001/*
002Copyright 2006 Jerry Huxtable
003
004Licensed under the Apache License, Version 2.0 (the "License");
005you may not use this file except in compliance with the License.
006You may obtain a copy of the License at
007
008   http://www.apache.org/licenses/LICENSE-2.0
009
010Unless required by applicable law or agreed to in writing, software
011distributed under the License is distributed on an "AS IS" BASIS,
012WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013See the License for the specific language governing permissions and
014limitations under the License.
015*/
016
017package com.jhlabs.image;
018
019import java.awt.*;
020import java.awt.image.*;
021import java.util.*;
022
023/**
024 * A filter which can be used to produce wipes by transferring the luma of a Destination image into the alpha channel of the source.
025 */
026public class ChromaKeyFilter extends AbstractBufferedImageOp {
027        
028        private float hTolerance = 0;
029        private float sTolerance = 0;
030        private float bTolerance = 0;
031        private int color;
032
033        public ChromaKeyFilter() {
034        }
035
036        /**
037         * Set the tolerance of the image in the range 0..1.
038         * *arg tolerance The tolerance
039         */
040        public void setHTolerance( float hTolerance ) {
041                this.hTolerance = hTolerance;
042        }
043        
044        public float getHTolerance() {
045                return hTolerance;
046        }
047        
048        public void setSTolerance( float sTolerance ) {
049                this.sTolerance = sTolerance;
050        }
051        
052        public float getSTolerance() {
053                return sTolerance;
054        }
055        
056        public void setBTolerance( float bTolerance ) {
057                this.bTolerance = bTolerance;
058        }
059        
060        public float getBTolerance() {
061                return bTolerance;
062        }
063        
064        public void setColor( int color ) {
065                this.color = color;
066        }
067        
068        public int getColor() {
069                return color;
070        }
071                
072    public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
073        int width = src.getWidth();
074        int height = src.getHeight();
075                int type = src.getType();
076                WritableRaster srcRaster = src.getRaster();
077
078        if ( dst == null )
079            dst = createCompatibleDestImage( src, null );
080                WritableRaster dstRaster = dst.getRaster();
081
082                float[] hsb1 = null;
083                float[] hsb2 = null;
084                int rgb2 = color;
085                int r2 = (rgb2 >> 16) & 0xff;
086                int g2 = (rgb2 >> 8) & 0xff;
087                int b2 = rgb2 & 0xff;
088                hsb2 = Color.RGBtoHSB( r2, b2, g2, hsb2 );
089                int[] inPixels = null;
090                for ( int y = 0; y < height; y++ ) {
091                        inPixels = getRGB( src, 0, y, width, 1, inPixels );
092                        for ( int x = 0; x < width; x++ ) {
093                                int rgb1 = inPixels[x];
094
095                                int r1 = (rgb1 >> 16) & 0xff;
096                                int g1 = (rgb1 >> 8) & 0xff;
097                                int b1 = rgb1 & 0xff;
098                                hsb1 = Color.RGBtoHSB( r1, b1, g1, hsb1 );
099//                    int tolerance = (int)(255*tolerance);
100//                    return Math.abs(r1-r2) <= tolerance && Math.abs(g1-g2) <= tolerance && Math.abs(b1-b2) <= tolerance;
101
102//                   if ( PixelUtils.nearColors( in, clean, (int)(255*tolerance) ) )
103                                if ( Math.abs( hsb1[0] - hsb2[0] ) < hTolerance && Math.abs( hsb1[1] - hsb2[1] ) < sTolerance && Math.abs( hsb1[2] - hsb2[2] ) < bTolerance )
104                                        inPixels[x] = rgb1 & 0xffffff;
105                                else
106                                        inPixels[x] = rgb1;
107                        }
108                        setRGB( dst, 0, y, width, 1, inPixels );
109                }
110
111        return dst;
112    }
113
114        public String toString() {
115                return "Keying/Chroma Key...";
116        }
117}