Java(swing)gif部分透明,当它不应该是 [英] Java (swing) gif partly transparent when it's not supposed to be

查看:271
本文介绍了Java(swing)gif部分透明,当它不应该是的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在java应用程序中显示动画gif。到目前为止,它显示和动画,但它应该是完全黑色或完全白色,它似乎变得透明,我可以看到在下面绘制的矩形的颜色。例如,这是我正在使用的一个GIF:





在黑色背景上它并不明显,但是当我将其更改为青色时:





真正奇怪的是,它似乎在第一帧正确显示,然后才会混淆。这是我用来获取和绘制图像的方法:

  //绘制标题
img = new 。的ImageIcon(Display.class.getResource(titlePath))的getImage();
g.drawImage(img,404,430,this);

我正在覆盖扩展JPanel的类中的paintcomponent,而我只是在调用那个重绘上课一次。



造成这种情况的原因是,这是一个已知问题还是我在实际绘制图像的方式上犯了错误?我无法找到任何关于此问题的文档。



提前致谢!



以下是两个



因此您的原始图像位于顶部且固定图像位于底部。背景颜色为红色以突出显示差异

  import java.awt.BorderLayout; 
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.imageio.IIOException;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.FileImageOutputStream;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

公共类MirrorImage {

public static void main(String [] args){
new MirrorImage();
}

public MirrorImage(){
EventQueue.invokeLater(new Runnable(){
@Override
public void run(){
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch(ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex){
}

JFrame框架= new JFrame(Testing);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

公共类TestPane扩展JPanel {

私有ImageIcon orig;
私人ImageIcon镜像;

public TestPane(){
mirror(new File(Qzlxj.gif),new File(Test.gif));
orig = new ImageIcon(Qzlxj.gif);
mirror = new ImageIcon(Test.gif);
}

@Override
public Dimension getPreferredSize(){
return mirror == null? new Dimension(200,200):new Dimension(orig.getIconWidth(),orig.getIconHeight()* 2);
}

@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
if(orig!= null){
Graphics2D g2d =(Graphics2D)g.create();
int x =(getWidth() - orig.getIconWidth())/ 2;
int y =(getHeight() - (orig.getIconHeight()* 2))/ 2;
g2d.drawImage(orig.getImage(),x,y,this);

// AffineTransform at = new AffineTransform();
// at.setToScale(1,-1);
// at.translate(0,-mirror.getIconHeight());
// g2d.setTransform(at);
g2d.drawImage(mirror.getImage(),x,y + mirror.getIconHeight(),this);
g2d.dispose();
}
}
}

public static void mirror(文件来源,File dest){

List< BufferedImage> images = new ArrayList<>(25);
列表<整数>延迟= new ArrayList<>(25);
int delay = 0;

ImageOutputStream output = null;
GifSequenceWriter writer = null;

try {

String [] imageatt = new String [] {
imageLeftPosition,
imageTopPosition,
imageWidth ,
imageHeight
};

ImageReader reader =(ImageReader)ImageIO.getImageReadersByFormatName(gif)。next();
ImageInputStream ciis = ImageIO.createImageInputStream(source);
reader.setInput(ciis,false);
int noi = reader.getNumImages(true);
BufferedImage master = null;

for(int i = 0; i< noi; i ++){

BufferedImage image = reader.read(i);
IIOMetadata metadata = reader.getImageMetadata(i);

节点树= metadata.getAsTree(javax_imageio_gif_image_1.0);
NodeList children = tree.getChildNodes();
for(int j = 0; j< children.getLength(); j ++){
Node nodeItem = children.item(j);
System.out.println(nodeItem.getNodeName());
if(nodeItem.getNodeName()。equals(ImageDescriptor)){
Map< String,Integer> imageAttr = new HashMap< String,Integer>();
NamedNodeMap attr = nodeItem.getAttributes();
// for(int index = 0; index< attr.getLength(); index ++){
// Node node = attr.item(index);
// System.out.println(---->+ node.getNodeName()+=+ node.getNodeValue());
//}
for(int k = 0; k< imageatt.length; k ++){
Node attnode = attr.getNamedItem(imageatt [k]);
imageAttr.put(imageatt [k],Integer.valueOf(attnode.getNodeValue()));
}

if(master == null){
master = new BufferedImage(imageAttr.get(imageWidth),imageAttr.get(imageHeight),BufferedImage。 TYPE_INT_ARGB);
}

Graphics2D g2d = master.createGraphics();
g2d.drawImage(image,imageAttr.get(imageLeftPosition),imageAttr.get(imageTopPosition),null);
g2d.dispose();

// BufferedImage frame = mirror(copyImage(master));
BufferedImage frame = copyImage(master);
ImageIO.write(frame,png,new File(img+ i +。png));
images.add(frame);

} else if(nodeItem.getNodeName()。equals(GraphicControlExtension)){
NamedNodeMap attr = nodeItem.getAttributes();
节点delayNode = attr.getNamedItem(delayTime);
if(delayNode!= null){
delay = Math.max(delay,Integer.valueOf(delayNode.getNodeValue()));
delays.add(延迟);
}
}
}

}

output = new FileImageOutputStream(dest);
writer = new GifSequenceWriter(output,images.get(0).getType(),delay * 10,true);

for(int i = 0; i< images.size(); i ++){
BufferedImage nextImage = images.get(i);
writer.writeToSequence(nextImage);
}
} catch(IOException e){
// TODO自动生成的catch块
e.printStackTrace();
}最后{
try {
writer.close();
} catch(例外e){
}
try {
output.close();
} catch(例外e){
}
}
}

公共静态BufferedImage镜像(BufferedImage img){

BufferedImage mirror = createCompatibleImage(img);
Graphics2D g2d = mirror.createGraphics();
AffineTransform at = new AffineTransform();
at.setToScale(1,-1);
at.translate(0,-img.getHeight());
g2d.setTransform(at);
g2d.drawImage(img,0,0,null);
g2d.dispose();

返回镜像;

}

public static BufferedImage copyImage(BufferedImage img){
int width = img.getWidth();
int height = img.getHeight();

BufferedImage newImage = createCompatibleImage(img);
Graphics graphics = newImage.createGraphics();

int x =(width - img.getWidth())/ 2;
int y =(height - img.getHeight())/ 2;

graphics.drawImage(img,x,y,img.getWidth(),img.getHeight(),null);
graphics.dispose();

返回newImage;
}

public static BufferedImage createCompatibleImage(BufferedImage image){
return getGraphicsConfiguration()。createCompatibleImage(image.getWidth(),image.getHeight(),image.getTransparency() );
}

public static GraphicsConfiguration getGraphicsConfiguration(){
return GraphicsEnvironment.getLocalGraphicsEnvironment()。getDefaultScreenDevice()。getDefaultConfiguration();
}

公共静态类GifSequenceWriter {

protected ImageWriter gifWriter;
protected ImageWriteParam imageWriteParam;
protected IIOMetadata imageMetaData;

/ **
*创建一个新的GifSequenceWriter
*
* @param outputStream将ImageOutputStream写入
* @param imageType其中一个在BufferedImage中指定的imageTypes
* @param timeBetweenFramesMS以毫秒为单位的帧之间的时间
* @param loopContinuously gher应该重复循环
* @throws IIOException如果没有找到gif ImageWriters
*
* @author Elliot Kroo(elliot [at] kroo [dot] net)
* /
public GifSequenceWriter(
ImageOutputStream outputStream,
int imageType,
int timeBetweenFramesMS,
boolean loopContinuously)抛出IIOException,IOException {
//我创建一个编写器的方法
gifWriter = getWriter();
imageWriteParam = gifWriter.getDefaultWriteParam();
ImageTypeSpecifier imageTypeSpecifier
= ImageTypeSpecifier.createFromBufferedImageType(imageType);

imageMetaData
= gifWriter.getDefaultImageMetadata(imageTypeSpecifier,
imageWriteParam);

String metaFormatName = imageMetaData.getNativeMetadataFormatName();

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

IIOMetadataNode graphicsControlExtensionNode = getNode(
root,
GraphicControlExtension);

// restoreToBackgroundColor
// restoreToPrevious
graphicsControlExtensionNode.setAttribute(disposalMethod,none);
graphicsControlExtensionNode.setAttribute(userInputFlag,FALSE);
graphicsControlExtensionNode.setAttribute(
transparentColorFlag,
FALSE);
graphicsControlExtensionNode.setAttribute(
delayTime,
Integer.toString(timeBetweenFramesMS / 10));
graphicsControlExtensionNode.setAttribute(
transparentColorIndex,
0);

IIOMetadataNode commentsNode = getNode(root,CommentExtensions);
commentsNode.setAttribute(CommentExtension,由MAH创建);

IIOMetadataNode appEntensionsNode = getNode(
root,
ApplicationExtensions);

IIOMetadataNode child = new IIOMetadataNode(ApplicationExtension);

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

int loop = loopContinuously? 0:1;

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

imageMetaData.setFromTree(metaFormatName,root);

gifWriter.setOutput(outputStream);

gifWriter.prepareWriteSequence(null);
}

public void writeToSequence(RenderedImage img)抛出IOException {
gifWriter.writeToSequence(
new IIOImage(
img,
null,
imageMetaData),
imageWriteParam);
}

/ **
*关闭此GifSequenceWriter对象。这不会关闭
*底层流,只需完成GIF。
* /
public void close()抛出IOException {
gifWriter.endWriteSequence();
}

/ **
*使用
* ImageIO.getImageWritersBySuffix(gif)返回第一个可用的GIF ImageWriter。
*
* @return一个GIF ImageWriter对象
* @throws IIOException如果没有返回GIF图像编写器
* /
private static ImageWriter getWriter()throws IIOException {
Iterator< ImageWriter> iter = ImageIO.getImageWritersBySuffix(gif);
if(!iter.hasNext()){
抛出新的IIOException(No GIF Image Writers Exists);
} else {
返回iter.next();
}
}

/ **
*返回现有的子节点,或创建并返回一个新的子
*节点(如果请求的节点不存在)。
*
* @param rootNode< tt> IIOMetadataNode< / tt>搜索子
*节点。
* @param nodeName子节点的名称。
*
* @return子节点(如果找到)或使用给定的
*名称创建的新节点。
* /
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);
}
}
}

最后,固定gif





以上是基于镜像动画gif的调查在Java中加载 - ImageIcon


I'm trying to display an animated gif inside a java application. So far it displays and animates, but where it's supposed to be either entirely black or entirely white it appears to become transparent and I can see the colour of the rectangle drawn underneath. For example, here's one of the gifs I'm using:

On a black background it's not noticeable, however when I change it to cyan:

What's really strange is that it seems like it's displaying correctly for the very first frame and then only messes up afterwards. This is the method I'm using to get and draw the image:

//Draw title
img = new ImageIcon(Display.class.getResource(titlePath)).getImage();
g.drawImage(img, 404, 430, this);

I'm overriding paintcomponent in a class that extends JPanel, and I'm only calling repaint on that class once.

What could be causing this, is it a known issue or am I making a mistake in the way I'm going about actually drawing the image? I haven't been able to find any sort of documentation about this issue.

Thanks in advance!

Here are two of the original gif files.

EDIT: Here's a sample of the code I wrote. I removed any unnecessary code to keep it short but kept everything related to the issue. It also may be worth noting that when I draw a png file (which is one of the frames used to create the gif) with the same method there's no issue. The gif was made on http://gifmaker.me/ in case it's relevant.

public class Display extends JPanel implements Constants{
    private GameData GD;
    private String currentImagePath;

    public Display(GameData gd){
        GD = gd;
        this.setPreferredSize(screenDimension);

        this.repaint();
    }

    public void draw(Location loc){
        currentImagePath = loc.getCurrentImagePath();

        this.repaint();
    }

    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.setColor(CYAN);
        g.fillRect(0, 0, screenW, screenH);

        Image img;

        if(OtherWorlds.isOnTitle == true){ //Title screen
            //Draw image
            img = new ImageIcon(Display.class.getResource(currentImagePath)).getImage();
            g.drawImage(img, 10, 10, this);

            //Draw other stuff

        {
        else{ //Regular location

            //Draw image
            img = new ImageIcon(Display.class.getResource(currentImagePath)).getImage();
            g.drawImage(img, 10, 10, this);

            //Other images and stuff in different areas
            //Drawn using the exact same method as above

            }

            //Random other lines and stuff
        }
    }
}

解决方案

When ever you have these types of problems, you want to start playing around with the disposalMethod of the frames.

I ran your gif through some inspection code and found the disposalMethod to be set to RESTORE_TO_BACKGROUND

So, basically, I took your gif and ran it through the following code, which created a new gif with the disposalMethod of none

So your original image is on top and the "fixed" image is on the bottom. The background is colored red to highlight the difference

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.imageio.IIOException;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.FileImageOutputStream;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class MirrorImage {

    public static void main(String[] args) {
        new MirrorImage();
    }

    public MirrorImage() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private ImageIcon orig;
        private ImageIcon mirror;

        public TestPane() {
            mirror(new File("Qzlxj.gif"), new File("Test.gif"));
            orig = new ImageIcon("Qzlxj.gif");
            mirror = new ImageIcon("Test.gif");
        }

        @Override
        public Dimension getPreferredSize() {
            return mirror == null ? new Dimension(200, 200) : new Dimension(orig.getIconWidth(), orig.getIconHeight() * 2);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (orig != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                int x = (getWidth() - orig.getIconWidth()) / 2;
                int y = (getHeight() - (orig.getIconHeight() * 2)) / 2;
                g2d.drawImage(orig.getImage(), x, y, this);

//                AffineTransform at = new AffineTransform();
//                at.setToScale(1, -1);
//                at.translate(0, -mirror.getIconHeight());
//                g2d.setTransform(at);
                g2d.drawImage(mirror.getImage(), x, y + mirror.getIconHeight(), this);
                g2d.dispose();
            }
        }
    }

    public static void mirror(File source, File dest) {

        List<BufferedImage> images = new ArrayList<>(25);
        List<Integer> delays = new ArrayList<>(25);
        int delay = 0;

        ImageOutputStream output = null;
        GifSequenceWriter writer = null;

        try {

            String[] imageatt = new String[]{
                "imageLeftPosition",
                "imageTopPosition",
                "imageWidth",
                "imageHeight"
            };

            ImageReader reader = (ImageReader) ImageIO.getImageReadersByFormatName("gif").next();
            ImageInputStream ciis = ImageIO.createImageInputStream(source);
            reader.setInput(ciis, false);
            int noi = reader.getNumImages(true);
            BufferedImage master = null;

            for (int i = 0; i < noi; i++) {

                BufferedImage image = reader.read(i);
                IIOMetadata metadata = reader.getImageMetadata(i);

                Node tree = metadata.getAsTree("javax_imageio_gif_image_1.0");
                NodeList children = tree.getChildNodes();
                for (int j = 0; j < children.getLength(); j++) {
                    Node nodeItem = children.item(j);
                    System.out.println(nodeItem.getNodeName());
                    if (nodeItem.getNodeName().equals("ImageDescriptor")) {
                        Map<String, Integer> imageAttr = new HashMap<String, Integer>();
                        NamedNodeMap attr = nodeItem.getAttributes();
//                        for (int index = 0; index < attr.getLength(); index++) {
//                            Node node = attr.item(index);
//                            System.out.println("----> " + node.getNodeName() + "=" + node.getNodeValue());
//                        }
                        for (int k = 0; k < imageatt.length; k++) {
                            Node attnode = attr.getNamedItem(imageatt[k]);
                            imageAttr.put(imageatt[k], Integer.valueOf(attnode.getNodeValue()));
                        }

                        if (master == null) {
                            master = new BufferedImage(imageAttr.get("imageWidth"), imageAttr.get("imageHeight"), BufferedImage.TYPE_INT_ARGB);
                        }

                        Graphics2D g2d = master.createGraphics();
                        g2d.drawImage(image, imageAttr.get("imageLeftPosition"), imageAttr.get("imageTopPosition"), null);
                        g2d.dispose();

//                        BufferedImage frame = mirror(copyImage(master));
                        BufferedImage frame = copyImage(master);
                        ImageIO.write(frame, "png", new File("img" + i + ".png"));
                        images.add(frame);

                    } else if (nodeItem.getNodeName().equals("GraphicControlExtension")) {
                        NamedNodeMap attr = nodeItem.getAttributes();
                        Node delayNode = attr.getNamedItem("delayTime");
                        if (delayNode != null) {
                            delay = Math.max(delay, Integer.valueOf(delayNode.getNodeValue()));
                            delays.add(delay);
                        }
                    }
                }

            }

            output = new FileImageOutputStream(dest);
            writer = new GifSequenceWriter(output, images.get(0).getType(), delay * 10, true);

            for (int i = 0; i < images.size(); i++) {
                BufferedImage nextImage = images.get(i);
                writer.writeToSequence(nextImage);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                writer.close();
            } catch (Exception e) {
            }
            try {
                output.close();
            } catch (Exception e) {
            }
        }
    }

    public static BufferedImage mirror(BufferedImage img) {

        BufferedImage mirror = createCompatibleImage(img);
        Graphics2D g2d = mirror.createGraphics();
        AffineTransform at = new AffineTransform();
        at.setToScale(1, -1);
        at.translate(0, -img.getHeight());
        g2d.setTransform(at);
        g2d.drawImage(img, 0, 0, null);
        g2d.dispose();

        return mirror;

    }

    public static BufferedImage copyImage(BufferedImage img) {
        int width = img.getWidth();
        int height = img.getHeight();

        BufferedImage newImage = createCompatibleImage(img);
        Graphics graphics = newImage.createGraphics();

        int x = (width - img.getWidth()) / 2;
        int y = (height - img.getHeight()) / 2;

        graphics.drawImage(img, x, y, img.getWidth(), img.getHeight(), null);
        graphics.dispose();

        return newImage;
    }

    public static BufferedImage createCompatibleImage(BufferedImage image) {
        return getGraphicsConfiguration().createCompatibleImage(image.getWidth(), image.getHeight(), image.getTransparency());
    }

    public static GraphicsConfiguration getGraphicsConfiguration() {
        return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
    }

    public static class GifSequenceWriter {

        protected ImageWriter gifWriter;
        protected ImageWriteParam imageWriteParam;
        protected IIOMetadata imageMetaData;

        /**
         * Creates a new GifSequenceWriter
         *
         * @param outputStream the ImageOutputStream to be written to
         * @param imageType one of the imageTypes specified in BufferedImage
         * @param timeBetweenFramesMS the time between frames in miliseconds
         * @param loopContinuously wether the gif should loop repeatedly
         * @throws IIOException if no gif ImageWriters are found
         *
         * @author Elliot Kroo (elliot[at]kroo[dot]net)
         */
        public GifSequenceWriter(
                ImageOutputStream outputStream,
                int imageType,
                int timeBetweenFramesMS,
                boolean loopContinuously) throws IIOException, IOException {
            // my method to create a writer
            gifWriter = getWriter();
            imageWriteParam = gifWriter.getDefaultWriteParam();
            ImageTypeSpecifier imageTypeSpecifier
                    = ImageTypeSpecifier.createFromBufferedImageType(imageType);

            imageMetaData
                    = gifWriter.getDefaultImageMetadata(imageTypeSpecifier,
                            imageWriteParam);

            String metaFormatName = imageMetaData.getNativeMetadataFormatName();

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

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

            //restoreToBackgroundColor
            //restoreToPrevious
            graphicsControlExtensionNode.setAttribute("disposalMethod", "none");
            graphicsControlExtensionNode.setAttribute("userInputFlag", "FALSE");
            graphicsControlExtensionNode.setAttribute(
                    "transparentColorFlag",
                    "FALSE");
            graphicsControlExtensionNode.setAttribute(
                    "delayTime",
                    Integer.toString(timeBetweenFramesMS / 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 = loopContinuously ? 0 : 1;

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

            imageMetaData.setFromTree(metaFormatName, root);

            gifWriter.setOutput(outputStream);

            gifWriter.prepareWriteSequence(null);
        }

        public 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);
        }
    }
}

And finally, the "fixed" gif

The above is based on the investigations from Mirroring animated gif on load in Java - ImageIcon

这篇关于Java(swing)gif部分透明,当它不应该是的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆