1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
package net.tylermurphy.ken.util;
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", "restoreToBackgroundColor");
graphicsControlExtensionNode.setAttribute("userInputFlag", "FALSE");
graphicsControlExtensionNode.setAttribute("transparentColorFlag", "TRUE");
graphicsControlExtensionNode.setAttribute("delayTime", Integer.toString(delay / 10));
graphicsControlExtensionNode.setAttribute("transparentColorIndex", "3");
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();
}
}
|