How to Generate GIF Image in Java with delay and infinite loop
This tutorial demonstrates how to generate GIF
image in java with customisable delay and infinite loop. This example enables you to create animations in GIF format using multiple images. You have the ability to set a delay between each image and you can enable an infinite loop.
Generate GIF Image with Delay and Infinite Loop
The following GifSequenceWriter
creates a GIF
image from multiple images.
package com.memorynotfound.image;
import javax.imageio.*;
import javax.imageio.metadata.IIOInvalidTreeException;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.RenderedImage;
import java.io.IOException;
public class GifSequenceWriter {
protected ImageWriter writer;
protected ImageWriteParam params;
protected IIOMetadata metadata;
public GifSequenceWriter(ImageOutputStream out, int imageType, int delay, boolean loop) throws IOException {
writer = ImageIO.getImageWritersBySuffix("gif").next();
params = writer.getDefaultWriteParam();
ImageTypeSpecifier imageTypeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(imageType);
metadata = writer.getDefaultImageMetadata(imageTypeSpecifier, params);
configureRootMetadata(delay, loop);
writer.setOutput(out);
writer.prepareWriteSequence(null);
}
private void configureRootMetadata(int delay, boolean loop) throws IIOInvalidTreeException {
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(delay / 10));
graphicsControlExtensionNode.setAttribute("transparentColorIndex", "0");
IIOMetadataNode commentsNode = getNode(root, "CommentExtensions");
commentsNode.setAttribute("CommentExtension", "Created by: https://memorynotfound.com");
IIOMetadataNode appExtensionsNode = getNode(root, "ApplicationExtensions");
IIOMetadataNode child = new IIOMetadataNode("ApplicationExtension");
child.setAttribute("applicationID", "NETSCAPE");
child.setAttribute("authenticationCode", "2.0");
int loopContinuously = loop ? 0 : 1;
child.setUserObject(new byte[]{ 0x1, (byte) (loopContinuously & 0xFF), (byte) ((loopContinuously >> 8) & 0xFF)});
appExtensionsNode.appendChild(child);
metadata.setFromTree(metaFormatName, root);
}
private static IIOMetadataNode getNode(IIOMetadataNode rootNode, String nodeName){
int nNodes = rootNode.getLength();
for (int i = 0; i < nNodes; i++){
if (rootNode.item(i).getNodeName().equalsIgnoreCase(nodeName)){
return (IIOMetadataNode) rootNode.item(i);
}
}
IIOMetadataNode node = new IIOMetadataNode(nodeName);
rootNode.appendChild(node);
return(node);
}
public void writeToSequence(RenderedImage img) throws IOException {
writer.writeToSequence(new IIOImage(img, null, metadata), params);
}
public void close() throws IOException {
writer.endWriteSequence();
}
}
Generate GIF Image Java
We create a new GifSequenceWriter
and pass in the destination file, the image type, the delay and infinite loop respectively. Next we write the first image and finally we loop over each image and add it to the gif using the SequenceWriter.writeToSequence()
.
package com.memorynotfound.image;
import javax.imageio.ImageIO;
import javax.imageio.stream.FileImageOutputStream;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.File;
public class CreateGifExample {
public static void main(String[] args) throws Exception {
BufferedImage first = ImageIO.read(new File("/tmp/duke.jpg"));
ImageOutputStream output = new FileImageOutputStream(new File("/tmp/example.gif"));
GifSequenceWriter writer = new GifSequenceWriter(output, first.getType(), 250, true);
writer.writeToSequence(first);
File[] images = new File[]{
new File("/tmp/duke-image-watermarked.jpg"),
new File("/tmp/duke.jpg"),
new File("/tmp/duke-text-watermarked.jpg"),
};
for (File image : images) {
BufferedImage next = ImageIO.read(image);
writer.writeToSequence(next);
}
writer.close();
output.close();
}
}
Converted Images
The generated GIF
image looks like this. We used a delay of 250 and the GIF
will infinity loop.
References
- ImageIO JavaDoc
- ImageWriter JavaDoc
- ImageWriteParam JavaDoc
- IIOMetadata JavaDoc
- ImageTypeSpecifier JavaDoc
- IIOMetadataNode JavaDoc
This helped me easily create a gif from Java. Thanks!
A small detail is that when loop is false it will loop once (running the animation twice). After some googling on the gif metadata I figured out if you don’t want to loop you shouldn’t add the NETSCAPE ApplicationExtension at all.