Java:在BufferedImages中拆分.GIF图像会产生格式错误的图像

时间:2019-01-30 14:35:47

标签: java image javax.imageio

因此,我有一小段代码,它以.gif图片作为输入,然后将此.gif图片拆分为BufferedImage数组。之后,它将图像存储在磁盘上的阵列中。当我这样做时,输出图像包含大量白像素噪点,这在输入.gif图像中不可见。

输入gif的示例:

Input gif

格式错误的输出图像示例(gif中的第三帧):

Malformed image

我用来分割gif的代码如下:

public static void main(String[] args) throws Exception {
        splitGif(new File("C:\\test.gif"));
}

public static void splitGif(File file) throws IOException {
    ImageReader reader = ImageIO.getImageReadersBySuffix("gif").next();     reader.setInput(ImageIO.createImageInputStream(new FileInputStream(file)), false);
    for(int i = 0; i < reader.getNumImages(true); i++) {
        BufferedImage image = reader.read(i);
        ImageIO.write(image, "PNG", new File(i + ".png"));
    }
}

有人可以帮我吗?

2 个答案:

答案 0 :(得分:1)

所以问题是,当将.gif文件读入Java时,给定帧中与前一帧相比不变的所有像素将完全透明。如果要读取.gif并将其拆分为正确渲染的BufferedImages数组,则必须用先前帧之一的最后一个非透明像素填充当前帧的透明像素。

代码:

public static void splitGif(File file) throws IOException {
    ImageReader reader = ImageIO.getImageReadersBySuffix("gif").next();
    reader.setInput(ImageIO.createImageInputStream(new FileInputStream(file)), false);
    BufferedImage lastImage = reader.read(0);
    ImageIO.write(lastImage, "PNG", new File(0 + ".png"));

    for (int i = 1; i < reader.getNumImages(true); i++) {
        BufferedImage image = makeImageForIndex(reader, i, lastImage);
        ImageIO.write(image, "PNG", new File(i + ".png"));
    }
}

private static BufferedImage makeImageForIndex(ImageReader reader, int index, BufferedImage lastImage) throws IOException {
    BufferedImage image = reader.read(index);
    BufferedImage newImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);

    if(lastImage != null) {
        newImage.getGraphics().drawImage(lastImage, 0, 0, null);
    }
    newImage.getGraphics().drawImage(image, 0, 0, null);

    return newImage;
}

答案 1 :(得分:0)

您自己解决了问题,但顺序很好:每个下一帧都是所有先前帧的累加,填充了当前帧中的透明像素。

public static void splitGif(File file) throws IOException {
    ImageReader reader = ImageIO.getImageReadersBySuffix("gif").next();
    reader.setInput(ImageIO.createImageInputStream(new FileInputStream(file)), false);
    BufferedImage outImage = null;
    Graphics2D g = null;    
    for (int i = 0; i < reader.getNumImages(true); i++) {
         BufferedImage image = reader.read(i);
         if (g == null) {
             BufferedImage outImage = new BufferedImage(image.getWidth(), image.getHeight(),
                     BufferedImage.TYPE_4BYTE_ABGR);
             g = (Graphics2D) outImage.getGraphics();
         }
         g.drawImage(lastImage, 0, 0, null);
         ImageIO.write(outImage, "PNG", new File(i + ".png"));
     }
     if (g != null) {
         g.displose();
     }
}
  • getGraphics==createGraphics应该与记录中的dispose保持平衡。