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.Graphics2D;
018    import java.awt.RenderingHints;
019    import java.awt.image.BufferedImage;
020    import java.awt.image.ColorModel;
021    
022    import railo.runtime.engine.ThreadLocalPageContext;
023    import railo.runtime.exp.FunctionException;
024    import railo.runtime.exp.PageException;
025    import railo.runtime.img.ImageUtil;
026    import railo.runtime.type.List;
027    import railo.runtime.type.Struct;
028    
029    /**
030     * Scales an image using bi-cubic interpolation, which can't be done with AffineTransformOp.
031     */
032    public class BicubicScaleFilter extends AbstractBufferedImageOp  implements DynFiltering {
033    
034            private int width;
035            private int height;
036    
037            /**
038         * Construct a BicubicScaleFilter which resizes to 32x32 pixels.
039         */
040        public BicubicScaleFilter() {
041                    this(32, 32);
042            }
043    
044            /**
045             * Constructor for a filter which scales the input image to the given width and height using bicubic interpolation.
046             * Unfortunately, it appears that bicubic actually looks worse than bilinear interpolation on most Java implementations,
047             * but you can be the judge.
048         * @param width the width of the output image
049         * @param height the height of the output image
050             */
051            public BicubicScaleFilter( int width, int height ) {
052                    this.width = width;
053                    this.height = height;
054            }
055    
056        public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
057            int w = src.getWidth();
058            int h = src.getHeight();
059    
060                    if ( dst == null ) {
061                            ColorModel dstCM = src.getColorModel();
062                            dst = new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(width, height), dstCM.isAlphaPremultiplied(), null);
063                    }
064    
065                    Graphics2D g = dst.createGraphics();
066                    g.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC );
067                    g.drawImage( src, 0, 0, width, height, null );
068                    g.dispose();
069    
070            return dst;
071        }
072    
073            public String toString() {
074                    return "Distort/Bicubic Scale";
075            }
076    
077            public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src);
078                    Object o;
079    
080                    // check for arguments not supported
081                    if(parameters.size()>0) {
082                            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 []");
083                    }
084    
085                    return filter(src, dst);
086            }
087    }