使用ImageMagick实现多张图片拼接为gif(多线程版)

官网: https://imagemagick.org/

直接上代码

java 复制代码
ExecutorService es = Executors.newFixedThreadPool(10);
List<File> images = getImageFiles(sceneDir);
CountDownLatch cdl = new CountDownLatch(images.size());
// 拷贝图片
for (File file : images) {
	System.out.println(file.getPath());
	final File dstImage = new File(deploySceneImageDir, file.getName());
	es.submit(new Runnable() {
		@Override
		public void run() {
			// todo 预处理
			cdl.countDown();
		}
	});
}

logger.info("等待图片预处理完成");
cdl.await();
String gifPath = String.join(File.separator,deploySceneDir,"poster.gif");
// 拼接gif
es.submit(new Runnable() {
	@Override
	public void run() {
		toGif(new File(deploySceneImageDir),gifPath,delay,0);
	}
});
logger.info("完成图片的处理");
es.shutdown();

checker

java 复制代码
public boolean toGif(File srcDir, String outputImagePath,int delay,int loop){
		File[] files = srcDir.listFiles();
		if(files == null){
			return false;
		}
		int gifExpectSize = 0;
		List<String> images = new ArrayList<>();
		for (File file : files) {
			images.add("\""+file.getPath()+"\"") ;// 处理"convert: unable to open image"问题
			gifExpectSize += file.length();
		}
		System.out.println("期望的gif大小:"+(gifExpectSize/1024.0/1024.0)+"M");
		String imagePaths = String.join(" ",images);
		return toGif(imagePaths,outputImagePath,delay,loop);
	}

toGif方法

java 复制代码
public boolean toGif(String inputImagePath, String outputImagePath,int delay,int loop){
		List<String> command = new ArrayList<>();
		// -delay参数应该在输入图像之前指定
		command.add("-delay");// 指定每一帧之间的延迟时间(以毫秒为单位),这里是100毫秒。
		command.add(delay+"");
		command.add(inputImagePath);
		command.add("-loop");
		command.add(loop+"");
		command.add(outputImagePath);
		return execute(command);
	}

execute方法

java 复制代码
public boolean execute(List<String> command) {
		command.add(0,convertPath);
		try {
			String execCommand = Arrays.toString(command.toArray())
					.replace(",","")
					.replace("[","")
					.replace("]","");
			System.out.println("图像处理命令:"+execCommand);
			// 执行命令
			ProcessBuilder pb = new ProcessBuilder(command);
			Process process = pb.start();
			// 处理标准错误流
			BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
			String line;
			while ((line = errorReader.readLine()) != null) {
				System.err.println(line);
			}
			// 等待命令执行完成
			int exitCode = process.waitFor();
			return  exitCode == 0;
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return false;
	}
java 复制代码
public List<File> getImageFiles(String sceneDir){
		List<File> ret = new ArrayList<>();
		if (new File(sceneDir).listFiles() == null) {
			return ret;
		}

		for (File file : new File(sceneDir).listFiles()) {
			if(file.getName().endsWith(".JPG")){
				ret.add(file);
			}
		}
		return ret;
	}
相关推荐
一点媛艺4 分钟前
Kotlin函数由易到难
开发语言·python·kotlin
姑苏风8 分钟前
《Kotlin实战》-附录
android·开发语言·kotlin
奋斗的小花生1 小时前
c++ 多态性
开发语言·c++
魔道不误砍柴功1 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2341 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨1 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
老猿讲编程2 小时前
一个例子来说明Ada语言的实时性支持
开发语言·ada
Chrikk3 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*3 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue3 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang