使用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;
	}
相关推荐
nenchoumi311910 分钟前
UE5 学习系列(九)光照系统介绍
java·学习·ue5
南無忘码至尊12 分钟前
Unity C# 入门基础知识点整理与实战技巧
开发语言·c#
江梦寻13 分钟前
软件工程教学评价
开发语言·后端·macos·架构·github·软件工程
iCxhust14 分钟前
汇编字符串比较函数
c语言·开发语言·汇编·单片机·嵌入式硬件
张乔2420 分钟前
spring boot项目整合mybatis实现多数据源的配置
java·spring boot·多数据源
GzlAndy25 分钟前
Tomcat调优
java·tomcat
美好的事情能不能发生在我身上27 分钟前
苍穹外卖Day11代码解析以及深入思考
java·spring boot·后端·spring·架构
辉辉健身中34 分钟前
Maven入门(够用)
java·maven
星火飞码iFlyCode1 小时前
【无标题】
java·前端·人工智能·算法
不良手残1 小时前
Redisson + Lettuce 在 Spring Boot 中的最佳实践方案
java·spring boot·redis·后端