使用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;
	}
相关推荐
say_fall1 分钟前
Python 核心语法与常用库完全指南
开发语言·python
喝醉酒的小白1 分钟前
如何安装 `.whl` 文件(Python Wheel 包)
开发语言·python
小尤笔记2 分钟前
【2024版】超详细Python+Pycharm安装保姆级教程,Python环境配置和使用指南,看完这一篇就够了
开发语言·ide·python·pycharm·编程语言·解释器
2401_882351523 分钟前
Flutter for OpenHarmony 商城App实战 - 地址编辑实现
android·java·flutter
数据大魔方5 分钟前
【期货量化入门】Python获取期货实时行情(TqSdk完整代码)
开发语言·python·区块链
爬山算法13 分钟前
Hibernate(47)Hibernate的会话范围(Scope)如何控制?
java·后端·hibernate
AIFQuant13 分钟前
2026 全球外汇免费实时行情汇率数据 API 接口大全
开发语言·python·websocket·金融·restful
雨中飘荡的记忆15 分钟前
Caffeine入门到实战
java
砚边数影15 分钟前
AI开发依赖引入:DL4J / Java-ML 框架 Maven 坐标配置
java·数据库·人工智能·深度学习·机器学习·ai·maven
一路向北North15 分钟前
nacos更改配置值后,应用提示Refresh keys changed 但是注入的值没有发生变化
java