1 package eu.svjatoslav.meviz.htmlindexer;
3 import javax.imageio.*;
4 import javax.imageio.metadata.IIOInvalidTreeException;
5 import javax.imageio.metadata.IIOMetadata;
6 import javax.imageio.metadata.IIOMetadataNode;
7 import javax.imageio.stream.ImageOutputStream;
8 import java.awt.image.RenderedImage;
9 import java.io.IOException;
12 * Source: https://memorynotfound.com/generate-gif-image-java-delay-infinite-loop-example/
14 public class GifSequenceWriter {
15 protected ImageWriter writer;
16 protected ImageWriteParam params;
17 protected IIOMetadata metadata;
19 public GifSequenceWriter(ImageOutputStream out, int imageType, int delay, boolean loop) throws IOException {
20 writer = ImageIO.getImageWritersBySuffix("gif").next();
21 params = writer.getDefaultWriteParam();
23 ImageTypeSpecifier imageTypeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(imageType);
24 metadata = writer.getDefaultImageMetadata(imageTypeSpecifier, params);
26 configureRootMetadata(delay, loop);
28 writer.setOutput(out);
29 writer.prepareWriteSequence(null);
32 private void configureRootMetadata(int delay, boolean loop) throws IIOInvalidTreeException {
33 String metaFormatName = metadata.getNativeMetadataFormatName();
34 IIOMetadataNode root = (IIOMetadataNode) metadata.getAsTree(metaFormatName);
36 IIOMetadataNode graphicsControlExtensionNode = getNode(root, "GraphicControlExtension");
37 graphicsControlExtensionNode.setAttribute("disposalMethod", "none");
38 graphicsControlExtensionNode.setAttribute("userInputFlag", "FALSE");
39 graphicsControlExtensionNode.setAttribute("transparentColorFlag", "FALSE");
40 graphicsControlExtensionNode.setAttribute("delayTime", Integer.toString(delay / 10));
41 graphicsControlExtensionNode.setAttribute("transparentColorIndex", "0");
43 IIOMetadataNode commentsNode = getNode(root, "CommentExtensions");
44 commentsNode.setAttribute("CommentExtension", "Created by: https://memorynotfound.com");
46 IIOMetadataNode appExtensionsNode = getNode(root, "ApplicationExtensions");
47 IIOMetadataNode child = new IIOMetadataNode("ApplicationExtension");
48 child.setAttribute("applicationID", "NETSCAPE");
49 child.setAttribute("authenticationCode", "2.0");
51 int loopContinuously = loop ? 0 : 1;
52 child.setUserObject(new byte[]{ 0x1, (byte) (loopContinuously & 0xFF), (byte) ((loopContinuously >> 8) & 0xFF)});
53 appExtensionsNode.appendChild(child);
54 metadata.setFromTree(metaFormatName, root);
57 private static IIOMetadataNode getNode(IIOMetadataNode rootNode, String nodeName){
58 int nNodes = rootNode.getLength();
59 for (int i = 0; i < nNodes; i++){
60 if (rootNode.item(i).getNodeName().equalsIgnoreCase(nodeName)){
61 return (IIOMetadataNode) rootNode.item(i);
64 IIOMetadataNode node = new IIOMetadataNode(nodeName);
65 rootNode.appendChild(node);
69 public void writeToSequence(RenderedImage img) throws IOException {
70 writer.writeToSequence(new IIOImage(img, null, metadata), params);
73 public void close() throws IOException {
74 writer.endWriteSequence();