使用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;
	}
相关推荐
zhixingheyi_tian15 分钟前
JVM 之 GCLocker
java·jvm
2zcode17 分钟前
项目文档:基于MATLAB图像处理的饮料瓶灌装液位检测系统设计与实现
开发语言·图像处理·matlab
码哥字节27 分钟前
把 Cursor 的烂输出变成好代码,这 10 个 Prompt 改造让我省了 80% 改稿时间
java·ai编程工具·cursor 配置·prompt 技巧
2503_9317124827 分钟前
10m/s超高速电梯:西奥XO-NEWIII如何树立行业速度标杆
java·大数据·数据库
月疯34 分钟前
np.where()[0]的用法
开发语言·python·numpy
折哥的程序人生 · 物流技术专研35 分钟前
第4篇:抽象工厂模式——产品族一键创建
java·设计模式·抽象工厂模式·创建型模式·编程进阶·产品族·扩充系列
正儿八经的少年35 分钟前
Spring Boot
java·spring boot·后端
z落落39 分钟前
C#五大加密算法(AES、DES、MD5、RSA、SHA)
开发语言·c#
未秃头的程序猿41 分钟前
虚拟线程用了一年,我真香了——10倍吞吐量是真实存在的
java·后端·面试
namexingyun43 分钟前
Scaling Law bug实战启示:从“虚胖“到“精瘦“的算力效率革命
开发语言·网络·人工智能·bug·ai编程