Package net.yacy.visualization

Source Code of net.yacy.visualization.AnimationGIF

/**
*  AnimationGIF
*  Copyright 2010 by Michael Christen
*  First released 20.11.2010 at http://yacy.net
*  $LastChangedDate: 2011-03-08 02:51:51 +0100 (Di, 08. Mär 2011) $
*  $LastChangedRevision: 7567 $
*  $LastChangedBy: low012 $
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License as published by the Free Software Foundation; either
*  version 2.1 of the License, or (at your option) any later version.
*  This library 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
*  Lesser General Public License for more details.
*  You should have received a copy of the GNU Lesser General Public License
*  along with this program in the file lgpl21.txt
*  If not, see <http://www.gnu.org/licenses/>.
*/

package net.yacy.visualization;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.Random;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOInvalidTreeException;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.ImageOutputStream;
import javax.imageio.stream.MemoryCacheImageOutputStream;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


public class AnimationGIF {
   
    private final static String formatName    = "javax_imageio_gif_image_1.0";
    private final static String aesNodeName   = "ApplicationExtensions";
    private final static String aeNodeName    = "ApplicationExtension";
    private final static String gceNodeName   = "GraphicControlExtension";
    private final static String delayNodeName = "delayTime";

    private int counter, loops;
    private IIOMetadata iiom;
    private ImageWriter writer;
    private ImageWriteParam iwp;
    private ImageOutputStream ios;
    private ByteArrayOutputStream baos;
   
    /**
     * create a gif animation producer
     * @param loops - number of loops for the animated images. -1 = no loops; 0 = indefinitely loops; else: number of loops
     */
    public AnimationGIF(int loops) {
        this.counter = 0;
        this.loops = loops;
        this.ios = null;
        this.writer = null;

        this.baos = new ByteArrayOutputStream();
        Iterator<ImageWriter> writerIterator = ImageIO.getImageWritersByFormatName("GIF");
        this.writer = writerIterator.next(); // com.sun.media.imageioimpl.plugins.gif.GIFImageWriter, com.sun.imageio.plugins.gif.GIFImageWriter
        this.ios = new MemoryCacheImageOutputStream(baos);
        this.writer.setOutput(ios);
        this.iwp = writer.getDefaultWriteParam();
    }
   
    /**
     * add an image to the animation
     * @param image the image
     * @param duration the frame time of the image in milliseconds
     * @throws IOException
     */
    public void addImage(RenderedImage image, int duration) throws IOException {
        if (this.counter == 0) {
            iiom = writer.getDefaultImageMetadata(ImageTypeSpecifier.createFromRenderedImage(image), iwp);
            writer.prepareWriteSequence(writer.getDefaultStreamMetadata(iwp));
        }
        if (this.counter == 0 && loops >= 0) {
            IIOMetadata imageMetadata2 = writer.getDefaultImageMetadata(ImageTypeSpecifier.createFromRenderedImage(image), iwp);
            try {
                setDelay(imageMetadata2, duration);
                setLoops(imageMetadata2, this.loops);
                writer.writeToSequence(new IIOImage(image, null, imageMetadata2), iwp);
            } catch (IIOInvalidTreeException e) {
                throw new IOException(e.getMessage());
            }
        } else try {
            setDelay(iiom, duration);
            writer.writeToSequence(new IIOImage(image, null, iiom), iwp);
        } catch (IIOInvalidTreeException e) {
            throw new IOException(e.getMessage());
        }
        this.counter++;
    }
   
    /**
     * produce the gif image as byte array
     * @return the gif image
     */
    public byte[] get() {
        if (ios != null) try {
            ios.close();
            ios = null;
        } catch (IOException e) {}
        if (writer != null) {
            writer.dispose();
            writer = null;
        }
        return baos.toByteArray();
    }
   
    private static void setDelay(IIOMetadata metaData, int delay) throws IIOInvalidTreeException {
        Node tree = metaData.getAsTree(formatName);
        NodeList nodeList = tree.getChildNodes();
        Node gceNode = null;
        for (int i = 0, len = nodeList.getLength(); i < len; i++) {
            Node curNode = nodeList.item(i);
            if (curNode.getNodeName().equals(gceNodeName)) {gceNode = curNode; break;}
        }
        if (gceNode == null) throw new IIOInvalidTreeException("Invalid image metadata, could not find " + gceNodeName + "node.", null, tree);
        Node delayNode = gceNode.getAttributes().getNamedItem(delayNodeName);
        if (delayNode == null) {
            delayNode = tree.getOwnerDocument().createAttribute(delayNodeName);
            gceNode.appendChild(delayNode);
        }
        delayNode.setNodeValue(Integer.valueOf(delay / 10).toString());
        metaData.setFromTree(formatName, tree);
    }
   
    /**
     * set number of loops for this animation
     * @param metaData
     * @param loops - 0 = loop continuously; 1-65535 = a specific number of loops
     * @throws IIOInvalidTreeException
     */
    private static void setLoops(IIOMetadata metaData, int loops) throws IIOInvalidTreeException {
        Node tree = metaData.getAsTree(formatName);
        IIOMetadataNode aes = new IIOMetadataNode(aesNodeName);
        IIOMetadataNode ae = new IIOMetadataNode(aeNodeName);
        ae.setAttribute("applicationID", "NETSCAPE");
        ae.setAttribute("authenticationCode", "2.0");
        ae.setUserObject(new byte[]{0x1, (byte) (loops & 0xFF), (byte) ((loops >> 8) & 0xFF)});
        aes.appendChild(ae);
        tree.appendChild(aes);
        metaData.setFromTree(formatName, tree);
    }
   
    /**
     * test image generator
     */
    private static RenderedImage generateTestImage(int width, int height, Random r, double angle) {
        BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics g = img.getGraphics();
        g.setColor(Color.white); g.fillRect(0, 0, width, height); g.setColor(Color.BLUE);
        int x = width / 2;
        int y = height / 2;
        int radius = Math.min(x, y);
        g.drawLine(x, y, x + (int) (radius * Math.cos(angle)), y + (int) (radius * Math.sin(angle)));
        g.drawString("giftest", r.nextInt(width), r.nextInt(height));
        return img;
    }

    public static void main(String[] args) {
        System.setProperty("java.awt.headless", "true"); // go into headless awt mode
        Random r = new Random(System.currentTimeMillis());
        int framescount = 100;
        AnimationGIF generator = new AnimationGIF(0);
        try {
            for (int i = 0; i < framescount; i++) {
                generator.addImage(generateTestImage(320, 160, r, i * 2 * Math.PI / framescount), 10);
            }
            FileOutputStream fos = new FileOutputStream(new File("/tmp/giftest.gif"));
            fos.write(generator.get());
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
TOP

Related Classes of net.yacy.visualization.AnimationGIF

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.