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.Rectangle; 018 import java.awt.image.BufferedImage; 019 020 import railo.runtime.engine.ThreadLocalPageContext; 021 import railo.runtime.exp.FunctionException; 022 import railo.runtime.exp.PageException; 023 import railo.runtime.img.ImageUtil; 024 import railo.runtime.type.KeyImpl; 025 import railo.runtime.type.List; 026 import railo.runtime.type.Struct; 027 028 /** 029 * An edge-detection filter. 030 */ 031 public class EdgeFilter extends WholeImageFilter implements DynFiltering { 032 033 public final static float R2 = (float)Math.sqrt(2); 034 035 public final static float[] ROBERTS_V = { 036 0, 0, -1, 037 0, 1, 0, 038 0, 0, 0, 039 }; 040 public final static float[] ROBERTS_H = { 041 -1, 0, 0, 042 0, 1, 0, 043 0, 0, 0, 044 }; 045 public final static float[] PREWITT_V = { 046 -1, 0, 1, 047 -1, 0, 1, 048 -1, 0, 1, 049 }; 050 public final static float[] PREWITT_H = { 051 -1, -1, -1, 052 0, 0, 0, 053 1, 1, 1, 054 }; 055 public final static float[] SOBEL_V = { 056 -1, 0, 1, 057 -2, 0, 2, 058 -1, 0, 1, 059 }; 060 public static float[] SOBEL_H = { 061 -1, -2, -1, 062 0, 0, 0, 063 1, 2, 1, 064 }; 065 public final static float[] FREI_CHEN_V = { 066 -1, 0, 1, 067 -R2, 0, R2, 068 -1, 0, 1, 069 }; 070 public static float[] FREI_CHEN_H = { 071 -1, -R2, -1, 072 0, 0, 0, 073 1, R2, 1, 074 }; 075 076 protected float[] vEdgeMatrix = SOBEL_V; 077 protected float[] hEdgeMatrix = SOBEL_H; 078 079 public EdgeFilter() { 080 } 081 082 public void setVEdgeMatrix(float[] vEdgeMatrix) { 083 this.vEdgeMatrix = vEdgeMatrix; 084 } 085 086 public float[] getVEdgeMatrix() { 087 return vEdgeMatrix; 088 } 089 090 public void setHEdgeMatrix(float[] hEdgeMatrix) { 091 this.hEdgeMatrix = hEdgeMatrix; 092 } 093 094 public float[] getHEdgeMatrix() { 095 return hEdgeMatrix; 096 } 097 098 protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) { 099 int index = 0; 100 int[] outPixels = new int[width * height]; 101 102 for (int y = 0; y < height; y++) { 103 for (int x = 0; x < width; x++) { 104 int r = 0, g = 0, b = 0; 105 int rh = 0, gh = 0, bh = 0; 106 int rv = 0, gv = 0, bv = 0; 107 int a = inPixels[y*width+x] & 0xff000000; 108 109 for (int row = -1; row <= 1; row++) { 110 int iy = y+row; 111 int ioffset; 112 if (0 <= iy && iy < height) 113 ioffset = iy*width; 114 else 115 ioffset = y*width; 116 int moffset = 3*(row+1)+1; 117 for (int col = -1; col <= 1; col++) { 118 int ix = x+col; 119 if (!(0 <= ix && ix < width)) 120 ix = x; 121 int rgb = inPixels[ioffset+ix]; 122 float h = hEdgeMatrix[moffset+col]; 123 float v = vEdgeMatrix[moffset+col]; 124 125 r = (rgb & 0xff0000) >> 16; 126 g = (rgb & 0x00ff00) >> 8; 127 b = rgb & 0x0000ff; 128 rh += (int)(h * r); 129 gh += (int)(h * g); 130 bh += (int)(h * b); 131 rv += (int)(v * r); 132 gv += (int)(v * g); 133 bv += (int)(v * b); 134 } 135 } 136 r = (int)(Math.sqrt(rh*rh + rv*rv) / 1.8); 137 g = (int)(Math.sqrt(gh*gh + gv*gv) / 1.8); 138 b = (int)(Math.sqrt(bh*bh + bv*bv) / 1.8); 139 r = PixelUtils.clamp(r); 140 g = PixelUtils.clamp(g); 141 b = PixelUtils.clamp(b); 142 outPixels[index++] = a | (r << 16) | (g << 8) | b; 143 } 144 145 } 146 return outPixels; 147 } 148 149 public String toString() { 150 return "Blur/Detect Edges"; 151 } 152 public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src); 153 Object o; 154 if((o=parameters.removeEL(KeyImpl.init("VEdgeMatrix")))!=null)setVEdgeMatrix(ImageFilterUtil.toAFloat(o,"VEdgeMatrix")); 155 if((o=parameters.removeEL(KeyImpl.init("HEdgeMatrix")))!=null)setHEdgeMatrix(ImageFilterUtil.toAFloat(o,"HEdgeMatrix")); 156 157 // check for arguments not supported 158 if(parameters.size()>0) { 159 throw new FunctionException(ThreadLocalPageContext.get(), "ImageFilter", 3, "parameters", "the parameter"+(parameters.size()>1?"s":"")+" ["+List.arrayToList(parameters.keysAsString(),", ")+"] "+(parameters.size()>1?"are":"is")+" not allowed, only the following parameters are supported [VEdgeMatrix, HEdgeMatrix]"); 160 } 161 162 return filter(src, dst); 163 } 164 }