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.image.*;
020import java.util.*;
021
022/**
023 * A filter which can be used to produce wipes by transferring the luma of a mask image into the alpha channel of the source.
024 */
025public class GradientWipeFilter extends AbstractBufferedImageOp {
026        
027        private float density = 0;
028        private float softness = 0;
029        private boolean invert;
030        private BufferedImage mask;
031
032        public GradientWipeFilter() {
033        }
034
035        /**
036         * Set the density of the image in the range 0..1.
037         * *arg density The density
038         */
039        public void setDensity( float density ) {
040                this.density = density;
041        }
042        
043        public float getDensity() {
044                return density;
045        }
046        
047        /**
048         * Set the softness of the dissolve in the range 0..1.
049         * @param softness the softness
050     * @min-value 0
051     * @max-value 1
052     * @see #getSoftness
053         */
054        public void setSoftness( float softness ) {
055                this.softness = softness;
056        }
057        
058        /**
059         * Get the softness of the dissolve.
060         * @return the softness
061     * @see #setSoftness
062         */
063        public float getSoftness() {
064                return softness;
065        }
066        
067        public void setMask( BufferedImage mask ) {
068                this.mask = mask;
069        }
070        
071        public BufferedImage getMask() {
072                return mask;
073        }
074        
075        public void setInvert( boolean invert ) {
076                this.invert = invert;
077        }
078        
079        public boolean getInvert() {
080                return invert;
081        }
082        
083    public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
084        int width = src.getWidth();
085        int height = src.getHeight();
086
087        if ( dst == null )
088            dst = createCompatibleDestImage( src, null );
089                if ( mask == null )
090                        return dst;
091
092        int maskWidth = mask.getWidth();
093        int maskHeight = mask.getHeight();
094
095                float d = density * (1+softness);
096                float lower = 255 * (d-softness);
097                float upper = 255 * d;
098
099                int[] inPixels = new int[width];
100                int[] maskPixels = new int[maskWidth];
101
102        for ( int y = 0; y < height; y++ ) {
103                        getRGB( src, 0, y, width, 1, inPixels );
104                        getRGB( mask, 0, y % maskHeight, maskWidth, 1, maskPixels );
105
106                        for ( int x = 0; x < width; x++ ) {
107                                int maskRGB = maskPixels[x % maskWidth];
108                                int inRGB = inPixels[x];
109                                int v = PixelUtils.brightness( maskRGB );
110                                float f = ImageMath.smoothStep( lower, upper, v );
111                                int a = (int)(255 * f);
112
113                                if ( invert )
114                                        a = 255-a;
115                                inPixels[x] = (a << 24) | (inRGB & 0x00ffffff);
116                        }
117
118                        setRGB( dst, 0, y, width, 1, inPixels );
119        }
120
121        return dst;
122    }
123
124        public String toString() {
125                return "Transitions/Gradient Wipe...";
126        }
127}