gpt4 book ai didi

Java:.gif 创建者需要调整

转载 作者:行者123 更新时间:2023-12-01 13:46:39 25 4
gpt4 key购买 nike

我目前正在创建一个程序(使用 Java)来导入图像,然后使用这些图像创建 .gif。

我的大多数图像都有透明背景,且 Alpha 设置为 0。

我当前的问题是,当我将一系列 8 张图像转换为一个 .gif 后,它们会相互渗透。换句话说,.gif 在绘制下一帧之前不会重新绘制图像。例如,如果一个苹果从树上掉下来,它看起来会像一条红色条纹,直到 .gif 循环为止。

我认为自己对 Java 非常精通,但我在搜索互联网文件时发现的脚本远远超出了我的能力范围。我的 8 本 Java 书籍中没有一本涉及 IIOMETANODE。而且互联网上的资源是有限的。所以我不确定iio的功能是什么。

这是脚本:

import javax.imageio.*;
import javax.imageio.metadata.*;
import javax.imageio.stream.*;

import java.awt.image.*;
import java.io.*;
import java.util.Iterator;

public class GifCreator {

private ImageWriter gifWriter;
private ImageWriteParam imageWriteParam;
private IIOMetadata imageMetaData;

public GifCreator(){}
/**
* Creates a new GifSequenceWriter
*
* @param output the ImageOutputStream to be written to
* @param imgType one of the imageTypes specified in BufferedImage
* @param frameTime the time between frames in miliseconds
* @param loop wether the gif should loop repeatedly
* @throws IIOException if no gif ImageWriters are found
*
*/
public GifCreator(ImageOutputStream output, int imgType, int frameTime, boolean loop)
{
try {
gifWriter = getWriter();
imageWriteParam = gifWriter.getDefaultWriteParam();
ImageTypeSpecifier imageTypeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(imgType);

imageMetaData = gifWriter.getDefaultImageMetadata(imageTypeSpecifier, imageWriteParam);

String metaFormatName = imageMetaData.getNativeMetadataFormatName();

IIOMetadataNode root = (IIOMetadataNode) imageMetaData.getAsTree(metaFormatName);

IIOMetadataNode graphicsControlExtensionNode = getNode(root, "GraphicControlExtension");

graphicsControlExtensionNode.setAttribute("disposalMethod", "none");
graphicsControlExtensionNode.setAttribute("userInputFlag", "FALSE");
graphicsControlExtensionNode.setAttribute("transparentColorFlag", "FALSE");
graphicsControlExtensionNode.setAttribute("delayTime", Integer.toString(frameTime / 10));
graphicsControlExtensionNode.setAttribute("transparentColorIndex", "0");

IIOMetadataNode appEntensionsNode = getNode(root, "ApplicationExtensions");

IIOMetadataNode child = new IIOMetadataNode("ApplicationExtension");

child.setAttribute("applicationID", "NETSCAPE");
child.setAttribute("authenticationCode", "2.0");

int aLoop = loop ? 0 : 1;

child.setUserObject(new byte[]{ 0x1, (byte) (aLoop & 0xFF), (byte) ((aLoop >> 8) & 0xFF)});
appEntensionsNode.appendChild(child);

imageMetaData.setFromTree(metaFormatName, root);

gifWriter.setOutput(output);

gifWriter.prepareWriteSequence(null);
} catch (Exception e) {
e.printStackTrace();
}
}

private void writeToSequence(RenderedImage img) throws IOException
{
gifWriter.writeToSequence(new IIOImage(img, null, imageMetaData), imageWriteParam);
}

/**
* Close this GifSequenceWriter object. This does not close the underlying
* stream, just finishes off the GIF.
*/
public void close() throws IOException
{
gifWriter.endWriteSequence();
}

/**
* Returns the first available GIF ImageWriter using
* ImageIO.getImageWritersBySuffix("gif").
*
* @return a GIF ImageWriter object
* @throws IIOException if no GIF image writers are returned
*/

private static ImageWriter getWriter() throws IIOException
{
Iterator<ImageWriter> iter = ImageIO.getImageWritersBySuffix("gif");

if (!iter.hasNext()) {
throw new IIOException("No GIF Image Writers Exist");
} else {
return iter.next();
}
}

/**
* Returns an existing child node, or creates and returns a new child node (if
* the requested node does not exist).
*
* @param rootNode the <tt>IIOMetadataNode</tt> to search for the child node.
* @param nodeName the name of the child node.
*
* @return the child node, if found or a new node created with the given name.
*/
private static 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);
}

public GifCreator(BufferedImage[] imgs, String path)
{
if (imgs.length <= 1)
return;

// Grabs the first BufferedImage from the array.
BufferedImage first = imgs[0];

try {
// Creates a new BufferedOutputStream with the incoming path.
ImageOutputStream output = new FileImageOutputStream(new File(path));

// Creates a gif sequence with the type of the first image, .1 second
// between frames, which loops continuously
GifCreator writer = new GifCreator(output, first.getType(), 100, true);

// write out the first image to our sequence...
writer.writeToSequence((RenderedImage) first);
for (int i = 1; i < imgs.length; i++) {
BufferedImage next = imgs[i];
writer.writeToSequence(next);
}

writer.close();
output.close();

} catch (Exception e) {
e.printStackTrace();
}
}
}

我再次尝试将 .gif 从出血图像一起更改。我尝试在两者之间创建一个缓冲区 BufferedImage,但失败了。

最佳答案

基本上,您需要更改disposalMethod...

graphicsControlExtensionNode.setAttribute("disposalMethod", "restoreToBackgroundColor");
graphicsControlExtensionNode.setAttribute("userInputFlag", "FALSE");
graphicsControlExtensionNode.setAttribute(
"transparentColorFlag",
"TRUE");

假设您添加的每个图像都是完整的图像,并且是对图像的优化“添加”

看看GIF Animation and Disposal Methods有关更多详细信息,如果您确实喜欢冒险,请访问 GIF specificationImage :: Java Animated GIFs (with transparant pixel disposal modes)其中列出了可能的处理方法,因此您可以尝试一下,看看哪些方法有效...

关于Java:.gif 创建者需要调整,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20318146/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com