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 import java.awt.image.WritableRaster; 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 * A filter which interpolates between two images. You can set the interpolation factor outside the range 0 to 1 030 * to extrapolate images. 031 */ 032 public class InterpolateFilter extends AbstractBufferedImageOp implements DynFiltering { 033 034 private BufferedImage destination; 035 private float interpolation; 036 037 public InterpolateFilter() { 038 } 039 040 /** 041 * Set the destination image. 042 * @param destination the destination image 043 * @see #getDestination 044 */ 045 public void setDestination( BufferedImage destination ) { 046 this.destination = destination; 047 } 048 049 /** 050 * Get the destination image. 051 * @return the destination image 052 * @see #setDestination 053 */ 054 public BufferedImage getDestination() { 055 return destination; 056 } 057 058 /** 059 * Set the interpolation factor. 060 * @param interpolation the interpolation factor 061 * @see #getInterpolation 062 */ 063 public void setInterpolation( float interpolation ) { 064 this.interpolation = interpolation; 065 } 066 067 /** 068 * Get the interpolation factor. 069 * @return the interpolation factor 070 * @see #setInterpolation 071 */ 072 public float getInterpolation() { 073 return interpolation; 074 } 075 076 public BufferedImage filter( BufferedImage src, BufferedImage dst ) { 077 int width = src.getWidth(); 078 int height = src.getHeight(); 079 int type = src.getType(); 080 WritableRaster srcRaster = src.getRaster(); 081 082 if ( dst == null ) 083 dst = createCompatibleDestImage( src, null ); 084 WritableRaster dstRaster = dst.getRaster(); 085 086 if ( destination != null ) { 087 width = Math.min( width, destination.getWidth() ); 088 height = Math.min( height, destination.getWidth() ); 089 int[] pixels1 = null; 090 int[] pixels2 = null; 091 092 for (int y = 0; y < height; y++) { 093 pixels1 = getRGB( src, 0, y, width, 1, pixels1 ); 094 pixels2 = getRGB( destination, 0, y, width, 1, pixels2 ); 095 for (int x = 0; x < width; x++) { 096 int rgb1 = pixels1[x]; 097 int rgb2 = pixels2[x]; 098 int a1 = (rgb1 >> 24) & 0xff; 099 int r1 = (rgb1 >> 16) & 0xff; 100 int g1 = (rgb1 >> 8) & 0xff; 101 int b1 = rgb1 & 0xff; 102 int a2 = (rgb2 >> 24) & 0xff; 103 int r2 = (rgb2 >> 16) & 0xff; 104 int g2 = (rgb2 >> 8) & 0xff; 105 int b2 = rgb2 & 0xff; 106 r1 = PixelUtils.clamp( ImageMath.lerp( interpolation, r1, r2 ) ); 107 g1 = PixelUtils.clamp( ImageMath.lerp( interpolation, g1, g2 ) ); 108 b1 = PixelUtils.clamp( ImageMath.lerp( interpolation, b1, b2 ) ); 109 pixels1[x] = (a1 << 24) | (r1 << 16) | (g1 << 8) | b1; 110 } 111 setRGB( dst, 0, y, width, 1, pixels1 ); 112 } 113 } 114 115 return dst; 116 } 117 118 public String toString() { 119 return "Effects/Interpolate..."; 120 } 121 public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src); 122 Object o; 123 if((o=parameters.removeEL(KeyImpl.init("Interpolation")))!=null)setInterpolation(ImageFilterUtil.toFloatValue(o,"Interpolation")); 124 if((o=parameters.removeEL(KeyImpl.init("destination")))!=null)setDestination(ImageFilterUtil.toBufferedImage(o,"destination")); 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":"")+" ["+List.arrayToList(parameters.keysAsString(),", ")+"] "+(parameters.size()>1?"are":"is")+" not allowed, only the following parameters are supported [Interpolation]"); 129 } 130 131 return filter(src, dst); 132 } 133 }