001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019/* 020* 021 022Licensed under the Apache License, Version 2.0 (the "License"); 023you may not use this file except in compliance with the License. 024You may obtain a copy of the License at 025 026 http://www.apache.org/licenses/LICENSE-2.0 027 028Unless required by applicable law or agreed to in writing, software 029distributed under the License is distributed on an "AS IS" BASIS, 030WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 031See the License for the specific language governing permissions and 032limitations under the License. 033*/ 034 035package lucee.runtime.img.filter;import java.awt.Rectangle; 036import java.awt.image.BufferedImage; 037 038import lucee.runtime.engine.ThreadLocalPageContext; 039import lucee.runtime.exp.FunctionException; 040import lucee.runtime.exp.PageException; 041import lucee.runtime.img.ImageUtil; 042import lucee.runtime.type.KeyImpl; 043import lucee.runtime.type.Struct; 044import lucee.runtime.type.util.CollectionUtil; 045 046/** 047 * Given a binary image, this filter performs binary erosion, setting all removed pixels to the given 'new' color. 048 */ 049public class ErodeFilter extends BinaryFilter implements DynFiltering { 050 051 private int threshold = 2; 052 053 public ErodeFilter() { 054 newColor = 0xffffffff; 055 } 056 057 /** 058 * Set the threshold - the number of neighbouring pixels for dilation to occur. 059 * @param threshold the new threshold 060 * @see #getThreshold 061 */ 062 public void setThreshold(int threshold) { 063 this.threshold = threshold; 064 } 065 066 /** 067 * Return the threshold - the number of neighbouring pixels for dilation to occur. 068 * @return the current threshold 069 * @see #setThreshold 070 */ 071 public int getThreshold() { 072 return threshold; 073 } 074 075 protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) { 076 int[] outPixels = new int[width * height]; 077 078 for (int i = 0; i < iterations; i++) { 079 int index = 0; 080 081 if (i > 0) { 082 int[] t = inPixels; 083 inPixels = outPixels; 084 outPixels = t; 085 } 086 for (int y = 0; y < height; y++) { 087 for (int x = 0; x < width; x++) { 088 int pixel = inPixels[y*width+x]; 089 if (blackFunction.isBlack(pixel)) { 090 int neighbours = 0; 091 092 for (int dy = -1; dy <= 1; dy++) { 093 int iy = y+dy; 094 int ioffset; 095 if (0 <= iy && iy < height) { 096 ioffset = iy*width; 097 for (int dx = -1; dx <= 1; dx++) { 098 int ix = x+dx; 099 if (!(dy == 0 && dx == 0) && 0 <= ix && ix < width) { 100 int rgb = inPixels[ioffset+ix]; 101 if (!blackFunction.isBlack(rgb)) 102 neighbours++; 103 } 104 } 105 } 106 } 107 108 if (neighbours >= threshold) { 109 if (colormap != null) 110 pixel = colormap.getColor((float)i/iterations); 111 else 112 pixel = newColor; 113 } 114 } 115 outPixels[index++] = pixel; 116 } 117 } 118 } 119 120 return outPixels; 121 } 122 123 public String toString() { 124 return "Binary/Erode..."; 125 } 126 127 public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src); 128 Object o; 129 if((o=parameters.removeEL(KeyImpl.init("Threshold")))!=null)setThreshold(ImageFilterUtil.toIntValue(o,"Threshold")); 130 if((o=parameters.removeEL(KeyImpl.init("Iterations")))!=null)setIterations(ImageFilterUtil.toIntValue(o,"Iterations")); 131 if((o=parameters.removeEL(KeyImpl.init("Colormap")))!=null)setColormap(ImageFilterUtil.toColormap(o,"Colormap")); 132 if((o=parameters.removeEL(KeyImpl.init("NewColor")))!=null)setNewColor(ImageFilterUtil.toColorRGB(o,"NewColor")); 133 134 // check for arguments not supported 135 if(parameters.size()>0) { 136 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 [Threshold, Iterations, Colormap, NewColor, BlackFunction]"); 137 } 138 139 return filter(src, dst); 140 } 141} 142