Java对GIF的简单删帧操作
来源:互联网 发布:淘宝虚拟专营入口 编辑:程序博客网 时间:2024/06/03 13:18
问题简介
最近在一些网站爬了一些搞笑动态图片,没想到保存好之后预览竟然是是这样:
用图片浏览器逐帧看了一下,原来每一张图片第一帧都是类似空白的画面,所以预览的缩略图也是第一张画面。
那么如果能用代码读取到GIF的每一帧,删除后在合并为一个新GIF那问题就解决了。
于是找了下Java 操作GIF图片的类库,最后在GitHub上找到了这个:
animated-gif-lib-for-java
方法简介
整个工程主要就两个java文件,一个用于解码的GifDecoder
类,一个用于编码的AnimatedGifEncoder
,另外有两个辅助类复制进来即可。
GifDecoder类
主要方法有:
public int read(String name)
指定需要解码的GIF图片路径,还有两个重载方法,支持读取
InputStream
和BufferedInputStream
public int getDelay(int n)
获取指定帧的延迟时间。
public int getFrameCount()
获取GIF图片的帧数
public int getLoopCount()
获取GIF图片的播放次数,0表示无限循环播放
public BufferedImage getFrame(int n)
获取指定帧的图像数据
AnimatedGifEncoder类
另一个是用于编码的AnimatedGifEncoder
类,方法和解码基本相反:
public void setDelay(int ms)
设置每帧之间的延迟时间,
GifDecoder
能获取到任意两帧之间的延迟,而AnimatedGifEncoder
貌似没有提供两帧之间的延迟设定,按照同一延迟时间处理。public void setRepeat(int iter)
设置播放次数,0表示无限循环播放
public boolean addFrame(BufferedImage im)
添加帧
public void setFrameRate(float fps)
设置帧率,与delay作用类似,相对设置delay为Math.round(100f / fps)
public boolean finish()
添加帧并配置好之后调用这个方法关闭文件输出流等
public boolean start(String file)
设置输出的文件路径,另一个重载方法以流的形式输出
另外AnimatedGifEncoder
还提供一些其他方法,包括设置透明度、背景颜色、图片质量、尺寸等。
代码
知道用法之后就简单了,先解码将原始GIF的所有帧数据、帧延迟、播放次数读取出来,然后再编码回去,同时删除第一帧即可。
这里除了点小问题,我的环境中Eclipse突然无法读取绝对路径,所以使用File.separator代替斜杠。
private String baseOutPath = "D:" + File.separator + "p" + File.separator+ "2" + File.separator; //存放解码出来的所有帧 private BufferedImage[] bi; //延迟时间 private int delay; public static void main(String[] args) throws IOException { GIFHandler handler = new GIFHandler(); dt.start(); } private void start() { //"D:/p/1",要转换的GIF图片目录 File gifPath = new File("D:" + File.separator + "p" + File.separator+ "1"); File[] gifs = null; //读取出所有GIF图片 if (gifPath.isDirectory()) { gifs = gifPath.listFiles(); } if (gifs != null && gifs.length != 0) { for (File f : gifs) { trans(f); System.out.println(f.getName()); } } System.out.println("转换完成"); } /** * 转换 */ private void trans(File transFile) { decode(transFile); encode(baseOutPath + transFile.getName()); } private void encode(String outPath) { AnimatedGifEncoder encoder = new AnimatedGifEncoder(); // 设置循环模式,0为无限循环 这里没有使用源文件的播放次数 encoder.setRepeat(0); // 设置输出路径 encoder.start(outPath); //这里从1开始,去掉第一帧 for (int i = 1; i < bi.length; i++) { encoder.setDelay(delay); encoder.addFrame(bi[i]); } encoder.finish(); } private void decode(File f) { GifDecoder decoder = new GifDecoder(); try { decoder.read(new FileInputStream(f)); } catch (FileNotFoundException e) { e.printStackTrace(); } // 获取到帧数 int frameCount = decoder.getFrameCount(); bi = new BufferedImage[frameCount]; // 获取到每一帧的数据保存到bi for (int i = 0; i < frameCount; i++) { bi[i] = decoder.getFrame(i); } // 获取到每帧之间的延迟时间,这里只取第一帧的 delay = decoder.getDelay(0); // ImageIO.write(frame, "jpeg", out); 该方法用于输出分解得到的单个图片文件 }
使用这两个类可以进行一些简单的帧操作,比如添加水印、设置延迟等。另外源码也不复杂,可以自行定义。
- Java对GIF的简单删帧操作
- Java 中对剪贴板的简单操作
- java对文件拷贝的简单操作
- Java 对JavaBean的简单内省操作
- java对execl的简单操作
- java对rendis 的简单操作
- Java对JSON的简单操作
- Java对Mysql的简单数据操作
- Java对cookie的简单操作
- 用Java对数据库进行简单操作的准备操作
- java swing 对数据库的简单操作例子
- java中对字符串的一些简单操作
- Java基础--对javaBean的简单内省操作
- JAVA基础加强之对javaBean的内省简单操作
- 关于java 对xml 的简单读写操作
- java中对gif的第一帧截取(支持背景透明)
- java实现对gif与jpg之间的相互转化
- 对xml的简单操作
- 如何查看Javascript原生对象的方法?
- POJ 2456 Aggressive cows——二分查找(最大化最小值)
- java实现翻转链表
- TCP连接的11种状态变迁
- 每日一题(24)—— const
- Java对GIF的简单删帧操作
- 【IO/NIO】Java NIO浅析
- Caffe基础系列【一】MNIST数据集的测试
- hadoop系列之一集群规划篇
- 函数模板不会进行自动的参数转换
- java面试题,各大企业常见的java笔试题之五
- 泛型简介,自定义泛型的应用及泛型在Dao层的应用
- linux常用工具命令
- 1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)