有时候需要自己录制一个gif图片的时候就不知道去哪里录制,所以只能在百度找一个可以录制gif图片的软件,但是你会发现,你能找到的免费导出的都是有水印的,所以你可能就需要找一个水印少一点的软件了,但是gif又不像是图片水印再少你也没办法直接去处理,但是你要的gif格式的图片肯定是不想有水印的,所以我就想一个办法,通过代码去处理!!
有钱人的话直接买会员的可以过了!
其实需求都是自己遇到的哈!!
既然用代码处理,那么就肯定想这一个方便处理的,这里我就找了一个水印不在中间的,那不在中间的水印我就可以裁剪的方式把水印去掉,保留中间部分我需要的图片,这里我就找到了一个水印在左上和右下的录制软件,如下图:
上面的图片就是我截取的gif中的一张图,可以看到左上和右下是有水印的(这里我打码了),那么这种的水印我们就很方便去处理了
通过下载的软件录制成上面的带有水印的gif图片,作为一个程序员,这种的处理方案应该算是很简单的一种了,至少一看到这样的我就想到用裁剪的方式,那裁剪我自己第一步是百度找站长工具在线裁剪,结果找的都是裁剪完带上了自己免费的裁剪工具的水印logo,所以根本满足不了自己的需求!那作为一个程序员总不能就这样放弃了!
所以果断找代码通过代码的方式去裁剪,因为裁剪的方式直接从左上角裁剪一定的范围就能满足需求了!
思路:
本来以为有直接的裁剪工具,但是网上找了一段时间要么不能运行,要么使用的库是自己封装的别人无法使用!!但是都是基于gif处理的!
所以最后的方案为:将gif的每一帧获取到,将每一帧读取为一张图片,然后通过裁剪每一帧的图片,将裁剪完的图片数组重新组成gif,这样得到的新的gif就是我们需要的了!!
这里我用的java
写的代码:
读取原来的gif
File file = new File("D:/demo.gif");
ImageReader imageReader = ImageIO.getImageReadersByFormatName("gif").next();
imageReader.setInput(ImageIO.createImageInputStream(file));
使用AnimatedGifEncoder
类创建一个新的gif对象,并设置相关属性
AnimatedGifEncoder encoder = new AnimatedGifEncoder();
encoder.start("D:/y.gif");
encoder.setDelay(0);
encoder.setRepeat(-1);
encoder.setFrameRate(60);
encoder.setQuality(1);
循环原来的gif的每一帧,生成图片,将生成的图片加入到创建的新的gif对象中
for(int i=0;i<imageReader.getNumImages(true);i++){
BufferedImage img = imageReader.read(i);
int x = 150; // 裁剪开始x坐标
int y = 80; // 裁剪开始y坐标
int width = 650; // 裁剪宽度
int height = 500; // 裁剪高度
BufferedImage cropped = img.getSubimage(x, y, width, height);
encoder.addFrame(cropped);
}
// 完成编码操作,生成GIF文件
encoder.finish();
// 释放ImageReader资源
imageReader.dispose();
关闭资源之后就能看到新生成的gif图片了,以下为新生成的gif截的一张图
import com.madgag.gif.fmsware.AnimatedGifEncoder;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class GifCrop {
public static void main(String[] args) {
try {
// 创建一个指向指定GIF文件的File对象
// 读取GIF文件
File file = new File("D:/demo.gif");
// 使用GIF格式的ImageReader从文件读取图像
ImageReader imageReader = ImageIO.getImageReadersByFormatName("gif").next();
// 设置ImageReader的输入为指定的文件
imageReader.setInput(ImageIO.createImageInputStream(file));
// 创建一个AnimatedGifEncoder对象,用于将图像帧编码为GIF动画
AnimatedGifEncoder encoder = new AnimatedGifEncoder();
// 指定输出的GIF文件路径
encoder.start("D:/y.gif");
// 设置每帧的延迟时间,单位为毫秒。这里设置为0,表示每帧立即显示
encoder.setDelay(0);
// 设置动画重复次数 -1表示无限次 (这里有一个问题 我上传到CSDN的处理后的gif动画如果设置为-1或者不设置都只执行一次!!!所以我上传CSDN的时候设置很大)
encoder.setRepeat(-1);
// 设置动画的帧速率,范围是0.01至100。这里设置为60,表示每秒显示60帧
encoder.setFrameRate(60);
// 设置动画颜色质量
encoder.setQuality(1);
// 开始读取图像帧,循环直到读取完所有帧 imageReader.getNumImages获取当前gif的帧数
for(int i=0;i<imageReader.getNumImages(true);i++){
// 从ImageReader读取帧图像
BufferedImage img = imageReader.read(i);
// 定义裁剪区域,这里将图像裁剪为150x80到800x500的区域
// 获取裁剪区域
int x = 150; // 裁剪开始x坐标
int y = 80; // 裁剪开始y坐标
int width = 650; // 裁剪宽度
int height = 500; // 裁剪高度
// 对当前帧图像进行裁剪
// 裁剪图像
BufferedImage cropped = img.getSubimage(x, y, width, height);
// 将裁剪后的图像帧添加到AnimatedGifEncoder中
encoder.addFrame(cropped);
}
// 完成编码操作,生成GIF文件
encoder.finish();
// 释放ImageReader资源
imageReader.dispose();
} catch (IOException e) {
// 处理IO异常,打印异常堆栈信息
e.printStackTrace();
}
}
}
Tips:
这里我是处理的gif来上传博客的,但是有一个问题没有解决(代码中也有提到),
encoder.setRepeat(-1)
这个方法设置-1在本地打开没有问题,但是上传到CSDN博客gif只播放了一次,正确的结果应该是播放无数次!!这个问题我自己没有解决,但是我设置了encoder.setRepeat(5000);
,设置播放5000次其实够满足我自己的需求了,所以就没有去处理这个问题了,等回头有时间继续处理!!如果有懂的大佬也可以告知一下!!