Java读写gif格式图片,解决ImageIO读取gif文件只读取第一帧的问题(read and write gif format pictures in Java)

本文介绍了如何使用Java处理GIF动画图像。通过Hutool库,实现了读取每一帧并输出新GIF的功能,解决了ImageIO.read()方法只能读取第一帧的问题。详细步骤包括引入Hutool库,逐帧读取并处理GIF,最后使用 AnimatedGifEncoder 类生成新的动画GIF。
//Java API方式读取gif
final BufferedImage bufferedImage = ImageIO.read(new File(dir + "6.gif"));
//输出到新的文件
ImageIO.write(bufferedImage,"gif",new FileOutputStream(new File(dir +  "6-out.gif")));
//发现6-out.gif变成了静态图片

原因 ImageIO.read(new File(dir + "6.gif")) 只读取到了gif文件第一帧图像

解决步骤:

1.引入hutool

<dependency>
   <groupId>cn.hutool</groupId>
   <artifactId>hutool-all</artifactId>
   <version>5.7.11</version>
</dependency>

说明:若不想引入hutool,可以参见 https://github.com/rtyley/animated-gif-lib-for-javaicon-default.png?t=L9C2https://github.com/rtyley/animated-gif-lib-for-java

2.逐帧读取gif文件

//这里模拟上传文件接口
final MockMultipartFile file = new MockMultipartFile("6.gif", new FileInputStream(new File(dir + "6.gif")));
GifDecoder d = new GifDecoder();
d.read(file.getInputStream());
int n = d.getFrameCount();
List<BufferedImage> frames = new ArrayList<>();
for (int i = 0; i < n; i++) {
     BufferedImage frame = d.getFrame(i);  // frame i
     int t = d.getDelay(i);  // display duration of frame in milliseconds
     // do something with frame ,比如gif打水印,非法图片鉴定等
     frames.add(frame);
}

3.输出新的gif

File output = new File(dir + "out/1919.gif");
AnimatedGifEncoder e = new AnimatedGifEncoder();
e.start(new FileOutputStream(output));
e.setDelay(1000 / 24);   // 1 frame per sec
for (BufferedImage image : frames) {
   e.addFrame(image);
}
e.finish();

Java在窗口上加载显示GIF动画图像,将多个独立的GIF图像串联在一起显示,形成GIF特有的动画形式。主要代码如下:   ImageIcon[] images; //用于动画的图标数组   Timer animationTimer;   int currentImage = 0; //当前图像编号   int delay = 500; //图像切换延迟   int width; //图像宽度   int height; //图像高度   public AnimatorIcon() //构造函数   {    setBackground(Color.white);    images = new ImageIcon[2]; //初始化数组    for (int i=0;i   images[i]=new ImageIcon(getClass().getResource("image" i ".gif")); //实例化图标    width = images[0].getIconWidth(); //初始化宽度值    height = images[0].getIconHeight(); //初始化高度值   }   public void paintComponent(Graphics g) { //重载组件绘制方法    super.paintComponent(g); //调用父类函数    images[currentImage].paintIcon(this,g,70,0); //绘制图标    currentImage=(currentImage 1)%2; //更改当前图像编号   }   public void actionPerformed(ActionEvent actionEvent) {    repaint();   }   public void startAnimation() { //开始动画    if (animationTimer==null) {    currentImage=0;    animationTimer=new Timer(delay, this); //实例化Timer对象    animationTimer.start(); //开始运行    } else if (!animationTimer.isRunning()) //如果没有运行    animationTimer.restart(); //重新运行   }   public void stopAnimation() {    animationTimer.stop(); //停止动画   }   public static void main(String args[]) {    AnimatorIcon animation = new AnimatorIcon(); //实例化动画图标    JFrame frame = new JFrame("动画图标"); //实例化窗口对象    frame.getContentPane().add(animation); //增加组件到窗口上    frame.setSize(200, 100); //设置窗口尺寸    frame.setVisible(true); //设置窗口可视    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //关闭窗口时退出程序    animation.startAnimation(); //开始动画
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值