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