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}