当前位置: 首页 > news >正文

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

官网: https://imagemagick.org/

直接上代码

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() {@Overridepublic void run() {// todo 预处理cdl.countDown();}});
}logger.info("等待图片预处理完成");
cdl.await();
String gifPath = String.join(File.separator,deploySceneDir,"poster.gif");
// 拼接gif
es.submit(new Runnable() {@Overridepublic void run() {toGif(new File(deploySceneImageDir),gifPath,delay,0);}
});
logger.info("完成图片的处理");
es.shutdown();

checker

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方法

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方法

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;}
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;}
http://www.lryc.cn/news/135976.html

相关文章:

  • 解释 RESTful API,以及如何使用它构建 web 应用程序。
  • 远程端口转发 实践 如何将物理机某一端口的服务转发到vps上,使得外网能访问到
  • 【uniapp 监听键盘弹起与收回】
  • 【Unity】如何制作小地图
  • 基于IMX6ULLmini的linux裸机开发系列八:按键处理实验
  • 数据结构好题总结
  • Java串口开发
  • Python nohup 启动python脚本,后台没有日志
  • 完美解决微信小程序使用复选框van-checkbox无法选中
  • IDEA报错:类文件具有错误的版本 61.0,应为52.0
  • Linux 挂载局域网内共享目录
  • FFmpeg解码32k大分辨率出现如下错误:Picture size 32768x32768 is invalid
  • EasyExcel+POI制作带有有效性校验及下拉联动的Excel模板
  • Unity怎么制作魔法火焰特效?Unity制作魔法火焰特效方法
  • 双基证券:房地产基本面仍处下行通道 政策有望促进走稳
  • 31、springboot 配置HTTP服务端口及如何通过WebServer实例动态获取项目中的HTTP端口
  • 会计如何使用ChatGPT提高工作效率
  • 【TypeScript】类型推论和类型别名
  • 字节码调教的入口 —— JVM 的寄生插件 javaagent 那些事
  • Blender卡通着色入门
  • 性能调优篇 一、Jvm监控及诊断工具-命令行篇
  • Docker部署MongoDB 5.0.5
  • Day18-2-地狱回调-Promise-async-await技术
  • echarts范围限制下性能问题
  • wazuh环境配置以及案例复现
  • 解决el-select回显异常 显示option选项的value 而不是显示label
  • 【【STM32-SPI通信协议】】
  • 板卡常用前端 数据表操作
  • 基于AVR128单片机世界电子时钟的设计
  • Electron学习2 使用Electron-vue和Vuetify UI库