使用imageinputstream和bufferedimage从gif动画创建png strip时失去透明度

时间:2013-09-20 03:09:29

标签: java png transparency bufferedimage animated-gif

我终于能够编写以下代码,该代码采用动画GIF并将其转换为png条。但由于某种原因,它失去了原来的GIF的透明度。有人可以建议我如何保持透明度

public class Main {
public static void main(String[] args) throws IOException {
    Object input = new File("C:\\Users\\drizzt\\Documents\\jax.gif");
    // or Object input = new FileInputStream("animated.gif");
    ImageInputStream stream = ImageIO.createImageInputStream(input);
    Iterator readers = ImageIO.getImageReaders(stream);
    if (!readers.hasNext())
        throw new RuntimeException("no image reader found");
    ImageReader reader = (ImageReader) readers.next();
    reader.setInput(stream); // don't omit this line!
    int n = reader.getNumImages(true); // don't use false!
    int h = reader.getHeight(0);
    int w = reader.getWidth(0);

    BufferedImage img = new BufferedImage(w * n, h,
            BufferedImage.TYPE_INT_RGB);
    boolean[] imagedrawn;
    imagedrawn = new boolean[n];

    // big.drawImage(outputimage, w*i, 0, null);

    System.out.println("numImages = " + n);

    for (int i = 0; i < n; i++) {
        BufferedImage image = reader.read(i);
        System.out.println("image[" + i + "] = " + image);
        // img = BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        // img.createGraphics()
        imagedrawn[i] = img.createGraphics().drawImage(image, w * i, 0,
                null);

    }

    try {
        // retrieve image
        // BufferedImage bi = getMyImage();
        File outputfile = new File("c:\\saved.png");
        ImageIO.write(img, "png", outputfile);
    } catch (IOException e) {

    }

    stream.close();
}

}

1 个答案:

答案 0 :(得分:1)

替换它:

BufferedImage img = new BufferedImage(w * n, h, BufferedImage.TYPE_INT_RGB);

BufferedImage img = new BufferedImage(w * n, h, BufferedImage.TYPE_INT_ARGB);

......你会有透明度。

可能更好,就是:

BufferedImage img = reader.getRawImageType(0).createBufferedImage(w * n, h);

然后你将保留GIF的精确图像布局,并且可能会得到一个较小的输出图像(这里的一个小细节,如果没有相应的颜色空间,getRawImageType可能会返回null Java,但这可能永远不会发生在GIF上。)

与此问题无关,但仍然是良好做法:每当您执行img.createGraphics()时,您还应该在完成绘画时在dispose()上致电Graphics2D。在循环之后移动createGraphics()并在循环之后移动dispose以获得更好的性能。

甚至可以完全避免绘图,并将每个帧的内容直接读入img,方法是用以下内容替换你的循环:

ImageReadParam param = reader.getDefaultReadParam();
param.setDestination(img);

for (int i = 0; i++; i < n) {
    param.setDestinationOffset(new Point(w * i, 0);
    reader.read(i, param);
}