Package org.apache.batik.ext.awt.image.renderable

Source Code of org.apache.batik.ext.awt.image.renderable.FilterResRable8Bit

/*****************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved.        *
* ------------------------------------------------------------------------- *
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in  *
* the LICENSE file.                                                         *
*****************************************************************************/

package org.apache.batik.ext.awt.image.renderable;

import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderableImage;
import java.awt.image.renderable.RenderContext;


import org.apache.batik.ext.awt.image.rendered.AffineRed;
import org.apache.batik.ext.awt.image.GraphicsUtil;

/**
* Interface for implementing filter resolution.
*
* @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
* @version $Id: FilterResRable8Bit.java,v 1.4 2001/04/30 22:01:03 deweese Exp $
*/
public class FilterResRable8Bit extends AbstractRable
    implements FilterResRable{

    /**
     * Filter resolution along the x-axis
     */
    private int filterResolutionX = -1;

    /**
     * Filter resolution along the y-axis
     */
    private int filterResolutionY = -1;

    /**
     * Returns the source to be cropped.
     */
    public Filter getSource() {
        return (Filter)srcs.get(0);
    }
   
    /**
     * Sets the source to be cropped
     * @param src image to offset.
     */
    public void setSource(Filter src){
        init(src, null);
    }

    /**
     * Returns the resolution along the X axis.
     */
    public int getFilterResolutionX(){
        return filterResolutionX;
    }

    /**
     * Sets the resolution along the X axis, i.e., the maximum
     * size for intermediate images along that axis.
     * The value should be greater than zero to have an effect.
     * Negative values are illegal.
     */
    public void setFilterResolutionX(int filterResolutionX){
        if(filterResolutionX < 0){
            throw new IllegalArgumentException();
        }
        this.filterResolutionX = filterResolutionX;
    }
   
    /**
     * Returns the resolution along the Y axis.
     */
    public int getFilterResolutionY(){
        return filterResolutionY;
    }

    /**
     * Sets the resolution along the Y axis, i.e., the maximum
     * size for intermediate images along that axis.
     * If the Y-value is less than zero, the scale applied to
     * the rendered images is computed to preserve the image's aspect ratio
     */
    public void setFilterResolutionY(int filterResolutionY){
        this.filterResolutionY = filterResolutionY;
    }
   
    /**
     *
     */
    public RenderedImage createRendering(RenderContext renderContext){
        // Get user space to device space transform
        AffineTransform usr2dev = renderContext.getTransform();
        if(usr2dev == null){
            usr2dev = new AffineTransform();
        }
       
        // As per specification, a value of zero for the
        // x-axis or y-axis causes the filter to produce
        // nothing.
        // The processing is done as follows:
        // + if the x resolution is zero, this is a no-op
        //   else compute the x scale.
        // + if the y resolution is zero, this is a no-op
        //   else compute the y resolution from the x scale
        //   and compute the corresponding y scale.
        // + if the y or x scale is less than one, insert
        //   an AffineRable.
        //   Else, return the source as is.
        float filterResolutionX = this.filterResolutionX;
        float filterResolutionY = this.filterResolutionY;
        // System.out.println("FilterResRable: " + filterResolutionX + "x" +
        //                    filterResolutionY);

        // Find out the renderable area
        Rectangle2D imageRect = getBounds2D();
        Rectangle   devRect;
        devRect = usr2dev.createTransformedShape(imageRect).getBounds();

        if(filterResolutionX > 1) {
            // Now, compare the devRect with the filter
            // resolution hints
            float scaleX = 1;
            float scaleY = 1;
            if(filterResolutionX < devRect.width){
                scaleX = filterResolutionX / (float)devRect.width;
            }

            if(filterResolutionY != 0){
                if(filterResolutionY < 0){
                    filterResolutionY = scaleX*(float)devRect.height;
                }

                if(filterResolutionY < devRect.height) {
                    scaleY = filterResolutionY / (float)devRect.height;
                }
               
                // Only resample if either scaleX or scaleY is
                // smaller than 1
                RenderableImage localSource = getSource();
                RenderContext localRenderContext = renderContext;
               
                if((scaleX < 1) || (scaleY < 1)){
                    // System.out.println("filterRes X " + filterResolutionX +
                    //                    " Y : " + filterResolutionY);

                    scaleX = scaleX < scaleY ? scaleX : scaleY;
                    scaleY = scaleX;

                    //
                    // Create a rendering that will be less than
                    // or equal to filterResolutionX by filterResolutionY.
                    //
                    AffineTransform newUsr2Dev
                        = AffineTransform.getScaleInstance(scaleX, scaleY);
                   
                    newUsr2Dev.concatenate(usr2dev);
                   
                    //
                    // Create a new RenderingContext
                    //
                    RenderContext newRenderContext
                        = (RenderContext)renderContext.clone();
                    newRenderContext.setTransform(newUsr2Dev);

                    Shape aoi = renderContext.getAreaOfInterest();
                    if (aoi == null)
                        aoi = getBounds2D();
                   
                    //
                    // We need to grow the area of interest by a few
                    // pixels in device space so the AffineRed can
                    // interpolate at the edges..
                    //
                    Rectangle2D newAOI = aoi.getBounds2D();
                    newAOI = new Rectangle2D.Double
                        (newAOI.getX()-1/scaleX,
                         newAOI.getY()-1/scaleY,
                         newAOI.getWidth()+2/scaleX,
                         newAOI.getHeight()+2/scaleY);

                    newRenderContext.setAreaOfInterest(newAOI);

                    //
                    // Now, use an AffineRable that will apply the
                    // resampling
                    //
                    AffineTransform resampleTxf
                        = AffineTransform.getScaleInstance(1/scaleX, 1/scaleY);
                   
                    RenderedImage result = null;
                    result = localSource.createRendering(newRenderContext);
                    if (result != null)
                        result = new AffineRed
                            (GraphicsUtil.wrap(result),
                             resampleTxf, renderContext.getRenderingHints());

                    return result;
                }

                return localSource.createRendering(localRenderContext);
            }
        }

        return null;
    }
}

TOP

Related Classes of org.apache.batik.ext.awt.image.renderable.FilterResRable8Bit

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.