ImageDelegate.java :  » Media » praxis » net » neilcsmith » ripl » delegates » Java Open Source

Java Open Source » Media » praxis 
praxis » net » neilcsmith » ripl » delegates » ImageDelegate.java
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2010 Neil C Smith.
 * 
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 3 only, as
 * published by the Free Software Foundation.
 * 
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 3 for more details.
 * 
 * You should have received a copy of the GNU General Public License version 3
 * along with this work; if not, see http://www.gnu.org/licenses/
 * 
 * 
 * Please visit http://neilcsmith.net if you need additional information or
 * have any questions.
 */
package net.neilcsmith.ripl.delegates;

import java.awt.Dimension;
import java.awt.Rectangle;
import java.io.IOException;
import java.net.URI;
import net.neilcsmith.ripl.utils.ResizeMode;
import net.neilcsmith.ripl.Surface;
import net.neilcsmith.ripl.SurfaceOp;
import net.neilcsmith.ripl.impl.BufferedImageSurface;
import net.neilcsmith.ripl.ops.Blend;
import net.neilcsmith.ripl.ops.Blit;
import net.neilcsmith.ripl.ops.Bounds;
import net.neilcsmith.ripl.ops.ScaledBlit;
import net.neilcsmith.ripl.utils.ResizeUtils;

/**
 *
 * @author Neil C Smith
 */
public class ImageDelegate extends AbstractDelegate {

//    private static Logger logger = Logger.getLogger(ImageDelegate.class.getName());
    private BufferedImageSurface source;
    private Cache cache;
    private ResizeMode mode;

    private ImageDelegate(BufferedImageSurface source, ResizeMode mode) {
        this.source = source;
        this.mode = mode;
    }

    private ImageDelegate(BufferedImageSurface source, ResizeMode mode, int outputWidth, int outputHeight) {
        this(source, mode);
        createCache(outputWidth, outputHeight);
    }

    public void setResizeMode(ResizeMode mode) {
        if (mode == null) {
            throw new NullPointerException();
        }
        if (this.mode.getType() != ResizeMode.Type.Stretch
                || mode.getType() != ResizeMode.Type.Stretch) {
            // if both types weren't Stretch we need to recache
            cache = null;
        }
        this.mode = mode;
    }

    public ResizeMode getResizeMode() {
        return mode;
    }

    @Override
    public void process(Surface surface) {
        int outputWidth = surface.getWidth();
        int outputHeight = surface.getHeight();
//            SurfaceGraphics sg = output.getGraphics();
//            // check cache
//            if (cache == null || outputWidth != cache.outputWidth
//                    || outputHeight != cache.outputHeight) {
//                createCache(outputWidth, outputHeight);
//            }
//            // check if we need to draw input on output
//            if (input != output) {
//                if (cache.image.getTransparency() != BufferedImage.OPAQUE ||
//                        cache.image.getWidth() != outputWidth ||
//                        cache.image.getHeight() != outputHeight) {
//                    sg.drawSurface(input, 0, 0);
//                }
//            }
//            // render image
//            sg.drawImage(cache.image, cache.x, cache.y);


        if (cache == null || outputWidth != cache.outputWidth
                || outputHeight != cache.outputHeight) {
            createCache(outputWidth, outputHeight);
        }
        // check if we need to draw input on output
//        if (input != surface) {
//            if (cache.surface.hasAlpha()
//                    || cache.surface.getWidth() != outputWidth
//                    || cache.surface.getHeight() != outputHeight) {
//                surface.process(Blit.op(), input);
//            }
//        }
        // render cache
//        surface.process(Blit.op(cache.x, cache.y), cache.surface);
        if (cache.srcBnds != null) {
            surface.process(Blit.op(Blend.NORMAL, cache.srcBnds, cache.x, cache.y), cache.surface);
        } else {
            surface.process(Blit.op(cache.x, cache.y), cache.surface);
        }

    }

    private void createCache(int outputWidth, int outputHeight) {
        int srcWidth = source.getWidth();
        int srcHeight = source.getHeight();
        if (srcWidth == outputWidth && srcHeight == outputHeight) {
            createIdentityCache();
        } else {
            createResizedCache(new Dimension(srcWidth, srcHeight),
                    new Dimension(outputWidth, outputHeight));
        }
    }

    private void createIdentityCache() {
//        int width = source.getWidth();
//        int height = source.getHeight();
//        if (source.getType() == BufferedImage.TYPE_INT_RGB ||
//                source.getType() == BufferedImage.TYPE_INT_ARGB_PRE) {
//            cache = new Cache(source, width, height, 0, 0);
//        } else {
//            BufferedImage image;
//            if (source.getTransparency() == BufferedImage.OPAQUE) {
//                image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//            } else {
//                image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);
//            }
//            image.getGraphics().drawImage(source, 0, 0, null);
//            cache = new Cache(image, width, height, 0, 0);
//        }
        cache = new Cache(source, null, source.getWidth(), source.getHeight(), 0, 0);
    }

    private void createResizedCache(Dimension srcDim, Dimension dstDim) {
        Rectangle srcBnds = new Rectangle();
        Rectangle dstBnds = new Rectangle();
        ResizeUtils.calculateBounds(srcDim, dstDim, mode, srcBnds, dstBnds);
        if (srcBnds.width == dstBnds.width && srcBnds.height == dstBnds.height) {
            cache = new Cache(source, new Bounds(srcBnds), dstDim.width, dstDim.height, dstBnds.x, dstBnds.y);
        } else {
            BufferedImageSurface s = new BufferedImageSurface(dstBnds.width, dstBnds.height, source.hasAlpha());
            SurfaceOp blit = ScaledBlit.op(Blend.NORMAL, new Bounds(srcBnds),
                    new Bounds(0, 0, dstBnds.width, dstBnds.height));
            s.process(blit, source);
            cache = new Cache(s, null, dstDim.width, dstDim.height, dstBnds.x, dstBnds.y);
        }

    }

    private class Cache {

        BufferedImageSurface surface;
        int outputWidth;
        int outputHeight;
        int x;
        int y;
        Bounds srcBnds;

        private Cache(BufferedImageSurface surface, Bounds srcBnds, int outputWidth, int outputHeight, int x, int y) {
            this.surface = surface;
            this.srcBnds = srcBnds;
            this.outputWidth = outputWidth;
            this.outputHeight = outputHeight;
            this.x = x;
            this.y = y;
        }
    }

    public static ImageDelegate create(URI uri, ResizeMode mode, Dimension guide) throws IOException {

        if (uri == null || mode == null) {
            throw new NullPointerException();
        }

        BufferedImageSurface image = BufferedImageSurface.load(uri);

        if (guide == null) {
            return new ImageDelegate(image, mode);
        } else {
            return new ImageDelegate(image, mode, guide.width, guide.height);
        }
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.