0

我终于能够编写以下代码,该代码采用动画 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();
}

}

4

1 回答 1

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 中保留确切的图像布局,并可能获得更小的输出图像(这里的一个小细节是,如果 Java 中没有相应的颜色空间,它getRawImageType可能会返回null,但这对于 GIF 可能永远不会发生)。

与问题无关,但仍然是一个很好的做法:每当你这样做时,img.createGraphics()你也应该调用何时完成绘画。移动循环外部和循环之后以获得更好的性能。dispose()Graphics2DcreateGraphics()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);
}
于 2013-09-20T12:33:12.073 回答