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.*;
020
021/**
022 * A filter which produces a rubber-stamp type of effect by performing a thresholded blur.
023 */
024public class StampFilter extends PointFilter {
025
026        private float threshold;
027        private float softness = 0;
028    private float radius = 5;
029        private float lowerThreshold3;
030        private float upperThreshold3;
031        private int white = 0xffffffff;
032        private int black = 0xff000000;
033
034        /**
035     * Construct a StampFilter.
036     */
037        public StampFilter() {
038                this(0.5f);
039        }
040
041        /**
042     * Construct a StampFilter.
043     * @param threshold the threshold value
044     */
045        public StampFilter( float threshold ) {
046                setThreshold( threshold );
047        }
048
049        /**
050         * Set the radius of the effect.
051         * @param radius the radius
052     * @min-value 0
053     * @see #getRadius
054         */
055        public void setRadius(float radius) {
056                this.radius = radius;
057        }
058        
059        /**
060         * Get the radius of the effect.
061         * @return the radius
062     * @see #setRadius
063         */
064        public float getRadius() {
065                return radius;
066        }
067
068        /**
069     * Set the threshold value.
070     * @param threshold the threshold value
071     * @see #getThreshold
072     */
073        public void setThreshold(float threshold) {
074                this.threshold = threshold;
075        }
076        
077        /**
078     * Get the threshold value.
079     * @return the threshold value
080     * @see #setThreshold
081     */
082        public float getThreshold() {
083                return threshold;
084        }
085        
086        /**
087         * Set the softness of the effect in the range 0..1.
088         * @param softness the softness
089     * @min-value 0
090     * @max-value 1
091     * @see #getSoftness
092         */
093        public void setSoftness(float softness) {
094                this.softness = softness;
095        }
096
097        /**
098         * Get the softness of the effect.
099         * @return the softness
100     * @see #setSoftness
101         */
102        public float getSoftness() {
103                return softness;
104        }
105
106        /**
107     * Set the color to be used for pixels above the upper threshold.
108     * @param white the color
109     * @see #getWhite
110     */
111        public void setWhite(int white) {
112                this.white = white;
113        }
114
115        /**
116     * Get the color to be used for pixels above the upper threshold.
117     * @return the color
118     * @see #setWhite
119     */
120        public int getWhite() {
121                return white;
122        }
123
124        /**
125     * Set the color to be used for pixels below the lower threshold.
126     * @param black the color
127     * @see #getBlack
128     */
129        public void setBlack(int black) {
130                this.black = black;
131        }
132
133        /**
134     * Set the color to be used for pixels below the lower threshold.
135     * @return the color
136     * @see #setBlack
137     */
138        public int getBlack() {
139                return black;
140        }
141
142    public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
143        dst = new GaussianFilter( (int)radius ).filter( src, null );
144        lowerThreshold3 = 255*3*(threshold - softness*0.5f);
145        upperThreshold3 = 255*3*(threshold + softness*0.5f);
146                return super.filter(dst, dst);
147        }
148
149        public int filterRGB(int x, int y, int rgb) {
150                int a = rgb & 0xff000000;
151                int r = (rgb >> 16) & 0xff;
152                int g = (rgb >> 8) & 0xff;
153                int b = rgb & 0xff;
154                int l = r + g + b;
155                float f = ImageMath.smoothStep(lowerThreshold3, upperThreshold3, l);
156        return ImageMath.mixColors(f, black, white);
157        }
158
159        public String toString() {
160                return "Stylize/Stamp...";
161        }
162}