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.image.BufferedImage; 018 019 import railo.runtime.engine.ThreadLocalPageContext; 020 import railo.runtime.exp.FunctionException; 021 import railo.runtime.exp.PageException; 022 import railo.runtime.img.ImageUtil; 023 import railo.runtime.type.KeyImpl; 024 import railo.runtime.type.Struct; 025 import railo.runtime.type.util.CollectionUtil; 026 027 028 029 public class PointillizeFilter extends CellularFilter implements DynFiltering { 030 031 private float edgeThickness = 0.4f; 032 private boolean fadeEdges = false; 033 private int edgeColor = 0xff000000; 034 private float fuzziness = 0.1f; 035 036 public PointillizeFilter() { 037 setScale(16); 038 setRandomness(0.0f); 039 } 040 041 public void setEdgeThickness(float edgeThickness) { 042 this.edgeThickness = edgeThickness; 043 } 044 045 public float getEdgeThickness() { 046 return edgeThickness; 047 } 048 049 public void setFadeEdges(boolean fadeEdges) { 050 this.fadeEdges = fadeEdges; 051 } 052 053 public boolean getFadeEdges() { 054 return fadeEdges; 055 } 056 057 public void setEdgeColor(int edgeColor) { 058 this.edgeColor = edgeColor; 059 } 060 061 public int getEdgeColor() { 062 return edgeColor; 063 } 064 065 public void setFuzziness(float fuzziness) { 066 this.fuzziness = fuzziness; 067 } 068 069 public float getFuzziness() { 070 return fuzziness; 071 } 072 073 public int getPixel(int x, int y, int[] inPixels, int width, int height) { 074 float nx = m00*x + m01*y; 075 float ny = m10*x + m11*y; 076 nx /= scale; 077 ny /= scale * stretch; 078 nx += 1000; 079 ny += 1000; // Reduce artifacts around 0,0 080 float f = evaluate(nx, ny); 081 082 float f1 = results[0].distance; 083 int srcx = ImageMath.clamp((int)((results[0].x-1000)*scale), 0, width-1); 084 int srcy = ImageMath.clamp((int)((results[0].y-1000)*scale), 0, height-1); 085 int v = inPixels[srcy * width + srcx]; 086 087 if (fadeEdges) { 088 float f2 = results[1].distance; 089 srcx = ImageMath.clamp((int)((results[1].x-1000)*scale), 0, width-1); 090 srcy = ImageMath.clamp((int)((results[1].y-1000)*scale), 0, height-1); 091 int v2 = inPixels[srcy * width + srcx]; 092 v = ImageMath.mixColors(0.5f*f1/f2, v, v2); 093 } else { 094 f = 1-ImageMath.smoothStep(edgeThickness, edgeThickness+fuzziness, f1); 095 v = ImageMath.mixColors(f, edgeColor, v); 096 } 097 return v; 098 } 099 100 public String toString() { 101 return "Stylize/Pointillize..."; 102 } 103 104 public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src); 105 Object o; 106 if((o=parameters.removeEL(KeyImpl.init("Fuzziness")))!=null)setFuzziness(ImageFilterUtil.toFloatValue(o,"Fuzziness")); 107 if((o=parameters.removeEL(KeyImpl.init("EdgeThickness")))!=null)setEdgeThickness(ImageFilterUtil.toFloatValue(o,"EdgeThickness")); 108 if((o=parameters.removeEL(KeyImpl.init("FadeEdges")))!=null)setFadeEdges(ImageFilterUtil.toBooleanValue(o,"FadeEdges")); 109 if((o=parameters.removeEL(KeyImpl.init("EdgeColor")))!=null)setEdgeColor(ImageFilterUtil.toColorRGB(o,"EdgeColor")); 110 if((o=parameters.removeEL(KeyImpl.init("Colormap")))!=null)setColormap(ImageFilterUtil.toColormap(o,"Colormap")); 111 if((o=parameters.removeEL(KeyImpl.init("Amount")))!=null)setAmount(ImageFilterUtil.toFloatValue(o,"Amount")); 112 if((o=parameters.removeEL(KeyImpl.init("Turbulence")))!=null)setTurbulence(ImageFilterUtil.toFloatValue(o,"Turbulence")); 113 if((o=parameters.removeEL(KeyImpl.init("Stretch")))!=null)setStretch(ImageFilterUtil.toFloatValue(o,"Stretch")); 114 if((o=parameters.removeEL(KeyImpl.init("Angle")))!=null)setAngle(ImageFilterUtil.toFloatValue(o,"Angle")); 115 if((o=parameters.removeEL(KeyImpl.init("AngleCoefficient")))!=null)setAngleCoefficient(ImageFilterUtil.toFloatValue(o,"AngleCoefficient")); 116 if((o=parameters.removeEL(KeyImpl.init("GradientCoefficient")))!=null)setGradientCoefficient(ImageFilterUtil.toFloatValue(o,"GradientCoefficient")); 117 if((o=parameters.removeEL(KeyImpl.init("F1")))!=null)setF1(ImageFilterUtil.toFloatValue(o,"F1")); 118 if((o=parameters.removeEL(KeyImpl.init("F2")))!=null)setF2(ImageFilterUtil.toFloatValue(o,"F2")); 119 if((o=parameters.removeEL(KeyImpl.init("F3")))!=null)setF3(ImageFilterUtil.toFloatValue(o,"F3")); 120 if((o=parameters.removeEL(KeyImpl.init("F4")))!=null)setF4(ImageFilterUtil.toFloatValue(o,"F4")); 121 if((o=parameters.removeEL(KeyImpl.init("Randomness")))!=null)setRandomness(ImageFilterUtil.toFloatValue(o,"Randomness")); 122 if((o=parameters.removeEL(KeyImpl.init("GridType")))!=null)setGridType(ImageFilterUtil.toString(o,"GridType")); 123 if((o=parameters.removeEL(KeyImpl.init("DistancePower")))!=null)setDistancePower(ImageFilterUtil.toFloatValue(o,"DistancePower")); 124 if((o=parameters.removeEL(KeyImpl.init("Scale")))!=null)setScale(ImageFilterUtil.toFloatValue(o,"Scale")); 125 126 // check for arguments not supported 127 if(parameters.size()>0) { 128 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 [Fuzziness, EdgeThickness, FadeEdges, EdgeColor, Colormap, Amount, Turbulence, Stretch, Angle, Coefficient, AngleCoefficient, GradientCoefficient, F1, F2, F3, F4, Randomness, GridType, DistancePower, Scale]"); 129 } 130 131 return filter(src, dst); 132 } 133 }