com.enterprisemath.utils.image.GifAnimatorWriter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of em-utils Show documentation
Show all versions of em-utils Show documentation
Collection of utility classes for large scale projects focusing on robust and testable code.
package com.enterprisemath.utils.image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
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.apache.commons.io.IOUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
/**
* Class which writes animation into a gif image file format.
* This library is derived from Animated GIF Writer original is at
* http://elliot.kroo.net/software/java/GifSequenceWriter/.
* License is Creative Commons Attribution 3.0 Unported License
* which allows you to do whatever you like as far as you remain the credit.
*
* @author radek.hecl
*
*/
public class GifAnimatorWriter {
/**
* Builder object.
*/
public static class Builder {
/**
* Builds the result object.
*
* @return created object
*/
public GifAnimatorWriter build() {
return new GifAnimatorWriter(this);
}
}
/**
* Creates new instance.
*
* @param builder builder object
*/
public GifAnimatorWriter(Builder builder) {
guardInvariants();
}
/**
* Guards this object to be consistent. Throws exception if this is not the case.
*/
private void guardInvariants() {
}
/**
* Writes animation as a gif file format and returns the data blob.
*
* @param animation animation which is captured
* @return data blob containing the gif encoded animation
*/
public byte[] writeAnimation(ImageAnimation animation) {
ImageWriter writer = ImageIO.getImageWritersBySuffix("gif").next();
ImageWriteParam param = writer.getDefaultWriteParam();
ImageTypeSpecifier imageTypeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_4BYTE_ABGR);
IIOMetadata metaData = writer.getDefaultImageMetadata(imageTypeSpecifier, param);
String metaFormatName = metaData.getNativeMetadataFormatName();
IIOMetadataNode root = (IIOMetadataNode) metaData.getAsTree(metaFormatName);
IIOMetadataNode graphicsControlExtensionNode = getNode(root, "GraphicControlExtension");
graphicsControlExtensionNode.setAttribute("disposalMethod", "none");
graphicsControlExtensionNode.setAttribute("userInputFlag", "FALSE");
graphicsControlExtensionNode.setAttribute("transparentColorFlag", "FALSE");
graphicsControlExtensionNode.setAttribute("delayTime", Integer.toString(animation.getFrameDuration() / 10));
graphicsControlExtensionNode.setAttribute("transparentColorIndex", "0");
IIOMetadataNode commentsNode = getNode(root, "CommentExtensions");
commentsNode.setAttribute("CommentExtension", "Created by MAH");
IIOMetadataNode appEntensionsNode = getNode(root, "ApplicationExtensions");
IIOMetadataNode child = new IIOMetadataNode("ApplicationExtension");
child.setAttribute("applicationID", "NETSCAPE");
child.setAttribute("authenticationCode", "2.0");
int loop = 0;
child.setUserObject(new byte[] { 0x1, (byte) (loop & 0xFF), (byte)
((loop >> 8) & 0xFF) });
appEntensionsNode.appendChild(child);
ByteArrayOutputStream os = null;
ImageOutputStream ios = null;
try {
os = new ByteArrayOutputStream();
ios = new MemoryCacheImageOutputStream(os);
metaData.setFromTree(metaFormatName, root);
writer.setOutput(ios);
writer.prepareWriteSequence(null);
for (int i = 0; i < animation.getNumFrames(); ++i) {
writer.writeToSequence(new IIOImage(animation.getFrame(i), null, metaData), param);
}
writer.endWriteSequence();
ios.close();
os.close();
ios = null;
} catch (IIOInvalidTreeException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (ios != null) {
try {
ios.close();
} catch (Exception e) {
// just suppress as this is suppose to be quiet
}
}
IOUtils.closeQuietly(os);
}
return os.toByteArray();
}
/**
* Returns an existing child node, or creates and returns a new child node (if
* the requested node does not exist).
*
* @param rootNode root node where the search begins
* @param nodeName the name of the child node
*
* @return founded child node or new node if specified node doesn't exists
*/
private IIOMetadataNode getNode(IIOMetadataNode rootNode, String nodeName) {
int nNodes = rootNode.getLength();
for (int i = 0; i < nNodes; i++) {
if (rootNode.item(i).getNodeName().compareToIgnoreCase(nodeName) == 0) {
return ((IIOMetadataNode) rootNode.item(i));
}
}
IIOMetadataNode node = new IIOMetadataNode(nodeName);
rootNode.appendChild(node);
return (node);
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
/**
* Creates new instance.
*
* @return created instance
*/
public static GifAnimatorWriter create() {
return new GifAnimatorWriter.Builder().
build();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy