package railo.runtime.functions.image; import java.awt.Composite; import java.awt.Font; import java.awt.Paint; import java.awt.Point; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.awt.image.BufferedImage; import java.awt.image.Kernel; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import railo.commons.lang.StringUtil; import railo.runtime.PageContext; import railo.runtime.exp.FunctionException; import railo.runtime.exp.PageException; import railo.runtime.img.Image; import railo.runtime.img.filter.*; import railo.runtime.img.math.BinaryFunction; import railo.runtime.img.math.Function2D; import railo.runtime.op.Caster; import railo.runtime.type.Struct; import railo.runtime.type.StructImpl; import railo.runtime.type.util.ListUtil; public class ImageFilter { private static final Struct EMPTY_STRUCT = new StructImpl(); private static Map<String,Class> filters=new HashMap<String, Class>(); static { filters.put("applymask",ApplyMaskFilter.class); filters.put("average",AverageFilter.class); filters.put("bicubicscale",BicubicScaleFilter.class); filters.put("block",BlockFilter.class); filters.put("blur",BlurFilter.class); filters.put("border",BorderFilter.class); filters.put("boxblur",BoxBlurFilter.class); filters.put("brushedmetal",BrushedMetalFilter.class); filters.put("bump",BumpFilter.class); filters.put("caustics",CausticsFilter.class); filters.put("cellular",CellularFilter.class); filters.put("channelmix",ChannelMixFilter.class); filters.put("check",CheckFilter.class); filters.put("chromakey",ChromaKeyFilter.class); filters.put("chrome",ChromeFilter.class); filters.put("circle",CircleFilter.class); ////////filters.put("composite",CompositeFilter.class); //filters.put("compound",CompoundFilter.class); filters.put("contour",ContourFilter.class); filters.put("contrast",ContrastFilter.class); filters.put("convolve",ConvolveFilter.class); filters.put("crop",CropFilter.class); filters.put("crystallize",CrystallizeFilter.class); filters.put("curl",CurlFilter.class); filters.put("curves",CurvesFilter.class); filters.put("despeckle",DespeckleFilter.class); filters.put("diffuse",DiffuseFilter.class); filters.put("diffusion",DiffusionFilter.class); filters.put("dilate",DilateFilter.class); filters.put("displace",DisplaceFilter.class); filters.put("dissolve",DissolveFilter.class); filters.put("dither",DitherFilter.class); filters.put("edge",EdgeFilter.class); filters.put("emboss",EmbossFilter.class); filters.put("equalize",EqualizeFilter.class); filters.put("erodealpha",ErodeAlphaFilter.class); filters.put("erode",ErodeFilter.class); filters.put("exposure",ExposureFilter.class); filters.put("fade",FadeFilter.class); filters.put("fbm",FBMFilter.class); filters.put("feedback",FeedbackFilter.class); filters.put("fieldwarp",FieldWarpFilter.class); filters.put("fill",FillFilter.class); filters.put("flare",FlareFilter.class); filters.put("flip",FlipFilter.class); filters.put("flush3d",Flush3DFilter.class); filters.put("fourcolor",FourColorFilter.class); filters.put("gain",GainFilter.class); filters.put("gamma",GammaFilter.class); filters.put("gaussian",GaussianFilter.class); filters.put("glint",GlintFilter.class); filters.put("glow",GlowFilter.class); filters.put("gradient",GradientFilter.class); filters.put("gradientwipe",GradientWipeFilter.class); filters.put("gray",GrayFilter.class); filters.put("grayscale",GrayscaleFilter.class); filters.put("halftone",HalftoneFilter.class); filters.put("hsbadjust",HSBAdjustFilter.class); filters.put("interpolate",InterpolateFilter.class); filters.put("invertalpha",InvertAlphaFilter.class); filters.put("invert",InvertFilter.class); //filters.put("iterated",IteratedFilter.class); filters.put("javalnf",JavaLnFFilter.class); filters.put("kaleidoscope",KaleidoscopeFilter.class); //filters.put("key",KeyFilter.class); filters.put("lensblur",LensBlurFilter.class); filters.put("levels",LevelsFilter.class); filters.put("life",LifeFilter.class); filters.put("light",LightFilter.class); filters.put("lookup",LookupFilter.class); filters.put("mapcolors",MapColorsFilter.class); filters.put("map",MapFilter.class); filters.put("marble",MarbleFilter.class); filters.put("marbletex",MarbleTexFilter.class); filters.put("mask",MaskFilter.class); filters.put("maximum",MaximumFilter.class); filters.put("median",MedianFilter.class); filters.put("minimum",MinimumFilter.class); filters.put("mirror",MirrorFilter.class); filters.put("motionblur",MotionBlurFilter.class); //filters.put("mutatable",MutatableFilter.class); filters.put("noise",NoiseFilter.class); filters.put("offset",OffsetFilter.class); filters.put("oil",OilFilter.class); filters.put("opacity",OpacityFilter.class); filters.put("outline",OutlineFilter.class); filters.put("perspective",PerspectiveFilter.class); filters.put("pinch",PinchFilter.class); filters.put("plasma",PlasmaFilter.class); filters.put("pointillize",PointillizeFilter.class); filters.put("polar",PolarFilter.class); filters.put("posterize",PosterizeFilter.class); //filters.put("premultiply",PremultiplyFilter.class); filters.put("quantize",QuantizeFilter.class); filters.put("quilt",QuiltFilter.class); filters.put("rays",RaysFilter.class); filters.put("reducenoise",ReduceNoiseFilter.class); filters.put("rendertext",RenderTextFilter.class); filters.put("rescale",RescaleFilter.class); filters.put("rgbadjust",RGBAdjustFilter.class); filters.put("ripple",RippleFilter.class); filters.put("rotate",RotateFilter.class); filters.put("saturation",SaturationFilter.class); filters.put("scale",ScaleFilter.class); filters.put("scratch",ScratchFilter.class); filters.put("shade",ShadeFilter.class); filters.put("shadow",ShadowFilter.class); filters.put("shape",ShapeFilter.class); filters.put("sharpen",SharpenFilter.class); filters.put("shatter",ShatterFilter.class); filters.put("shear",ShearFilter.class); filters.put("shine",ShineFilter.class); filters.put("skeleton",SkeletonFilter.class); //filters.put("sky",SkyFilter.class); filters.put("smartblur",SmartBlurFilter.class); filters.put("smear",SmearFilter.class); filters.put("solarize",SolarizeFilter.class); filters.put("sparkle",SparkleFilter.class); filters.put("sphere",SphereFilter.class); filters.put("stamp",StampFilter.class); filters.put("swim",SwimFilter.class); filters.put("texture",TextureFilter.class); filters.put("threshold",ThresholdFilter.class); filters.put("tileimage",TileImageFilter.class); //filters.put("transfer",TransferFilter.class); //filters.put("transform",TransformFilter.class); //filters.put("transition",TransitionFilter.class); filters.put("twirl",TwirlFilter.class); //filters.put("unpremultiply",UnpremultiplyFilter.class); filters.put("unsharp",UnsharpFilter.class); filters.put("variableblur",VariableBlurFilter.class); //filters.put("warp",WarpFilter.class); filters.put("water",WaterFilter.class); filters.put("weave",WeaveFilter.class); filters.put("wholeimage",WholeImageFilter.class); filters.put("wood",WoodFilter.class); } public static String call(PageContext pc, Object name, String filterName) throws PageException { return call(pc, name, filterName, EMPTY_STRUCT); } public static String call(PageContext pc, Object name, String filterName, Struct parameters) throws PageException { if(name instanceof String) name=pc.getVariable(Caster.toString(name)); Image img = Image.toImage(name); String lcFilterName = filterName.trim().toLowerCase(); // get filter class Class clazz = filters.get(lcFilterName); if(clazz==null) { String[] keys = filters.keySet().toArray(new String[filters.size()]); Arrays.sort(keys); String list=ListUtil.arrayToList(keys, ", "); String soundex = StringUtil.soundex(filterName); java.util.List<String> similar=new ArrayList<String>(); for(int i=0;i<keys.length;i++){ if(StringUtil.soundex(keys[i]).equals(soundex)) similar.add(keys[i]); } if(similar.size()>0) { list=ListUtil.arrayToList(similar.toArray(new String[similar.size()]), ", "); throw new FunctionException(pc, "ImageFilter", 2, "filtername", "invalid filter name ["+filterName+"], did you mean ["+list+"]"); } throw new FunctionException(pc, "ImageFilter", 2, "filtername", "invalid filter name ["+filterName+"], valid filter names are ["+list+"]"); } // load filter DynFiltering filter=null; try { filter=(DynFiltering) clazz.newInstance(); } catch (Throwable t) { throw Caster.toPageException(t); } // execute filter BufferedImage bi = img.getBufferedImage(); //BufferedImage empty = bi;//ImageUtil.createBufferedImage(bi); img.image(filter.filter(bi, parameters)); return null; } private static void setters(String key, Class clazz, StringBuilder sb) { //sb.append("Object o;\n"); sb.append(" public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src);\n"); sb.append(" Object o;\n"); Method[] methods = clazz.getMethods(); Method method; StringBuilder names=new StringBuilder(); for(int i=0;i<methods.length;i++){ method=methods[i]; if(method.getName().startsWith("set") && !method.getName().equals("setRGB") && !method.getName().equals("setDestination")){ String name=method.getName().substring(3); args(key,name,method,sb,i); if(names.length()>0) names.append(", "); names.append(name); } } sb.append("\n"); sb.append(" // check for arguments not supported\n"); sb.append(" if(parameters.size()>0) {\n"); sb.append(" throw new FunctionException(ThreadLocalPageContext.get(), \"ImageFilter\", 3, \"parameters\", \"the parameter\"+(parameters.size()>1?\"s\":\"\")+\" [\"+List.arrayToList(parameters.keys(),\", \")+\"] \"+(parameters.size()>1?\"are\":\"is\")+\" not allowed, only the following parameters are supported ["+names+"]\");\n"); sb.append(" }\n"); sb.append("\n"); sb.append(" return filter(src, dst);\n"); sb.append(" }\n"); } private static void args(String className, String name, Method method, StringBuilder sb, int methodIndex) { Class[] params = method.getParameterTypes(); if(params.length==1){ sb.append(" if((o=parameters.removeEL(KeyImpl.init(\""+name+"\")))!=null)"); sb.append(method.getName()+"("); arg(name, params[0], method,sb,methodIndex); sb.append(");\n"); } else if(params.length==2 && name.equals("Dimensions")){ sb.append(" if((o=parameters.removeEL(KeyImpl.init(\""+name+"\")))!=null){\n"); sb.append(" int[] dim=ImageFilterUtil.toDimensions(o,\"Dimensions\");\n"); sb.append(" "+method.getName()+"(dim[0],dim[1]"); sb.append(");\n"); sb.append(" }\n"); } //else print.e(className+"->"+method); } private static void arg(String name, Class param, Method method, StringBuilder sb, int methodIndex) { sb.append("ImageFilterUtil."); if(param==float.class) sb.append("toFloatValue"); else if(param==boolean.class) sb.append("toBooleanValue"); else if(param==int.class) sb.append("toIntValue"); else if(param==Point2D.class) sb.append("toPoint2D"); else if(param==WarpGrid.class) sb.append("toWarpGrid"); else if(param==Kernel.class) sb.append("toKernel"); else if(param==Colormap.class) sb.append("toColormap"); else if(param==Function2D.class) sb.append("toFunction2D"); else if(param==BufferedImage.class) sb.append("toBufferedImage"); else if(param==BinaryFunction.class) sb.append("toBinaryFunction"); else if(param==String.class) sb.append("toString"); else if(param==Paint.class) sb.append("toPaint"); else if(param==Font.class) sb.append("toFont"); else if(param==AffineTransform.class) sb.append("toAffineTransform"); else if(param==Composite.class) sb.append("toComposite"); else if(param==LightFilter.Material.class) sb.append("toLightFilter$Material"); //else if(param==FieldWarpFilter.Line.class) sb.append("toFieldWarpFilter$Line"); else if(param==FieldWarpFilter.Line[].class) sb.append("toAFieldWarpFilter$Line"); else if(param==CurvesFilter.Curve.class) sb.append("toCurvesFilter$Curve"); else if(param==CurvesFilter.Curve[].class) sb.append("toACurvesFilter$Curve"); else if(param==Point.class) sb.append("toPoint"); else if(param==int[].class) sb.append("toAInt"); else if(param==int[][].class) sb.append("toAAInt"); else if(param==float[].class) sb.append("toAFloat"); else { new RuntimeException(name+"!!!!!!!!!!!!!"+param.getName()).printStackTrace(); } sb.append("(o,\""+name+"\")"); } }