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.image.BufferedImage; 036 037import lucee.runtime.engine.ThreadLocalPageContext; 038import lucee.runtime.exp.FunctionException; 039import lucee.runtime.exp.PageException; 040import lucee.runtime.img.ImageUtil; 041import lucee.runtime.type.KeyImpl; 042import lucee.runtime.type.Struct; 043import lucee.runtime.type.util.CollectionUtil; 044 045/** 046 * A filter which adds Gaussian blur to an image, producing a glowing effect. 047 * 048 */ 049public class GlowFilter extends GaussianFilter implements DynFiltering { 050 051 private float amount = 0.5f; 052 053 public GlowFilter() { 054 radius = 2; 055 } 056 057 /** 058 * Set the amount of glow. 059 * @param amount the amount 060 * @min-value 0 061 * @max-value 1 062 * @see #getAmount 063 */ 064 public void setAmount( float amount ) { 065 this.amount = amount; 066 } 067 068 /** 069 * Get the amount of glow. 070 * @return the amount 071 * @see #setAmount 072 */ 073 public float getAmount() { 074 return amount; 075 } 076 077 public BufferedImage filter( BufferedImage src, BufferedImage dst ) { 078 int width = src.getWidth(); 079 int height = src.getHeight(); 080 081 if ( dst == null ) 082 dst = createCompatibleDestImage( src, null ); 083 084 int[] inPixels = new int[width*height]; 085 int[] outPixels = new int[width*height]; 086 src.getRGB( 0, 0, width, height, inPixels, 0, width ); 087 088 if ( radius > 0 ) { 089 convolveAndTranspose(kernel, inPixels, outPixels, width, height, alpha, alpha && premultiplyAlpha, false, CLAMP_EDGES); 090 convolveAndTranspose(kernel, outPixels, inPixels, height, width, alpha, false, alpha && premultiplyAlpha, CLAMP_EDGES); 091 } 092 093 src.getRGB( 0, 0, width, height, outPixels, 0, width ); 094 095 float a = 4*amount; 096 097 int index = 0; 098 for ( int y = 0; y < height; y++ ) { 099 for ( int x = 0; x < width; x++ ) { 100 int rgb1 = outPixels[index]; 101 int r1 = (rgb1 >> 16) & 0xff; 102 int g1 = (rgb1 >> 8) & 0xff; 103 int b1 = rgb1 & 0xff; 104 105 int rgb2 = inPixels[index]; 106 int r2 = (rgb2 >> 16) & 0xff; 107 int g2 = (rgb2 >> 8) & 0xff; 108 int b2 = rgb2 & 0xff; 109 110 r1 = PixelUtils.clamp( (int)(r1 + a * r2) ); 111 g1 = PixelUtils.clamp( (int)(g1 + a * g2) ); 112 b1 = PixelUtils.clamp( (int)(b1 + a * b2) ); 113 114 inPixels[index] = (rgb1 & 0xff000000) | (r1 << 16) | (g1 << 8) | b1; 115 index++; 116 } 117 } 118 119 dst.setRGB( 0, 0, width, height, inPixels, 0, width ); 120 return dst; 121 } 122 123 public String toString() { 124 return "Blur/Glow..."; 125 } 126 public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src); 127 Object o; 128 if((o=parameters.removeEL(KeyImpl.init("Amount")))!=null)setAmount(ImageFilterUtil.toFloatValue(o,"Amount")); 129 if((o=parameters.removeEL(KeyImpl.init("Radius")))!=null)setRadius(ImageFilterUtil.toFloatValue(o,"Radius")); 130 if((o=parameters.removeEL(KeyImpl.init("EdgeAction")))!=null)setEdgeAction(ImageFilterUtil.toString(o,"EdgeAction")); 131 if((o=parameters.removeEL(KeyImpl.init("UseAlpha")))!=null)setUseAlpha(ImageFilterUtil.toBooleanValue(o,"UseAlpha")); 132 if((o=parameters.removeEL(KeyImpl.init("PremultiplyAlpha")))!=null)setPremultiplyAlpha(ImageFilterUtil.toBooleanValue(o,"PremultiplyAlpha")); 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 [Amount, Radius, Kernel, EdgeAction, UseAlpha, PremultiplyAlpha]"); 137 } 138 139 return filter(src, dst); 140 } 141}