使用ffmepg工具,这里就不过多阐述,详细的可查看,我之前的博客。java
准备20张图片,我这里的二十张图片都是加了时间水印的图片(你也能够找不同的图片,能看出切换的效果就行)。app
功能:须要把20张图片合成视频工具
思路:首先咱们存放在本地的图片,通常都是按日期存放的,例如20190515165200.jpg,若是咱们要使用ffmepg,合成视频,就须要新建立一个文件夹temp,并把之前的图片复制到temp文件下,注意,必定要知足正则,否则,ffmepeg是没法识别的ui
注意下面的图片名称格式:都是知足正则表示%2d,由于视频的合成,会根据排序索引一直到最后,若是中间有中断,视频也会终止合成。线程
这句话如何理解?code
咱们经过下面的图片发现名称前面的名称是一直+1的,假设咱们把05改为22,说明视频到图片04就中止勒,合成的视频指挥包含0-4的图片。视频
package com.qihui.qxj.services.system; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.junit.Test; public class Test1 { /** * 把图片拼接成视频,这里取20张图片,生成10秒的视频 */ @Test public void test3() { long startTime =System.currentTimeMillis(); List commend = new ArrayList(); commend.add("c:/bin/ffmpeg.exe"); //以1fps读入 commend.add("-r"); commend.add("4"); //-threads 2 以两个线程进行运行, 加快处理的速度。 commend.add("-threads"); commend.add("2"); commend.add("-f"); commend.add("image2"); commend.add("-i"); commend.add("d:/project/destimg/40/test/%2d.jpg"); commend.add("-vcodec"); commend.add("libx264"); //-y 对输出文件进行覆盖 commend.add("-y"); //-r 5 fps设置为5帧/秒(不一样位置有不一样含义) %2d标识图片文件的正则 commend.add("-r"); commend.add("10"); commend.add("d:/out.mp4"); start(commend); long endTime =System.currentTimeMillis(); System.out.println((endTime-startTime)); } private void start(List commend) { Process p = null; try { ProcessBuilder builder = new ProcessBuilder(commend); builder.command(commend); p = builder.start(); p.getOutputStream().close(); doWaitFor(p); p.destroy(); } catch (Exception e) { PrintCatchErrorMsg.Print(e, "Part", "getRSTPPicture.catch", "Exception"); p.destroy(); } } public static int doWaitFor(Process p) { InputStream in = null; InputStream err = null; int exitValue = -1; try { in = p.getInputStream(); err = p.getErrorStream(); boolean finished = false; while(!finished) { try { Character c; while(in.available() > 0) { c = new Character((char)in.read()); System.out.print(c); } while(err.available() > 0) { c = new Character((char)err.read()); System.out.print(c); } exitValue = p.exitValue(); finished = true; } catch (IllegalThreadStateException var19) { Thread.currentThread(); Thread.sleep(500L); } } } catch (Exception var20) { } finally { try { if (in != null) { in.close(); } } catch (IOException var18) { } if (err != null) { try { err.close(); } catch (IOException var17) { } } } return exitValue; } }
-r在不一样位置,产生的意思不同,-r放在-i前,表示输入,这里我设置的4,表示1秒4帧,20个图片,也就是5秒。对象
/** * 把图片拼接成视频,这里取20张图片,生成10秒的视频 */ @Test public void test3() { long startTime =System.currentTimeMillis(); List commend = new ArrayList(); commend.add("c:/bin/ffmpeg.exe"); //以1fps读入 commend.add("-r"); commend.add("4"); //-threads 2 以两个线程进行运行, 加快处理的速度。 commend.add("-threads"); commend.add("2"); commend.add("-f"); commend.add("image2"); commend.add("-i"); commend.add("d:/project/destimg/40/test1/%2d.jpg"); commend.add("-i"); commend.add("d:/1557906953.jpg"); commend.add("-filter_complex"); commend.add((new StringBuilder("[1:v]scale=150:150[s];[0:v][s]overlay=")).append(1800).append(":").append(900) .toString()); commend.add("-vcodec"); commend.add("libx264"); //-y 对输出文件进行覆盖 commend.add("-y"); //-r 5 fps设置为5帧/秒(不一样位置有不一样含义) %2d标识图片文件的正则 commend.add("-r"); commend.add("10"); commend.add("d:/out.mp4"); start(commend); long endTime =System.currentTimeMillis(); System.out.println((endTime-startTime)); }
对比上面,多个图片合成视频的代码,视频加上图片水印,多了以下代码:blog
commend.add("-i");
commend.add("d:/1557906953.jpg"); //这是图片水印,也就是上图的那个正方形排序
commend.add("-filter_complex"); //设置滤镜
commend.add((new StringBuilder("[1:v]scale=150:150[s];[0:v][s]overlay=")).append(1800).append(":").append(900)
.toString());
其余的代码,一目了然,很容易懂,可能添加滤镜这段代码很难懂,下面咱们把它拆分一下
[1:v]这个里头两个参数,1表示的是操做对象的编号。在本例中0就是图片须要合成视频的有序目录地址,1就是1557906953.png,3就是output.mp4。而另外一个参数v表示操做对象里的视频信息。
[1:v]scale=150:150[s];[0:v][s]overlay=1800:900
因此这头一句[1:v]scale=150:150[s];的意思就是对图片1557906953.png进行调节尺寸的操做,并将这个操做的结果命名为s
下一句[0:v][s]overlay=1800:900的意思就是对视频添加水印的的结果s添加水印,overlay就是水印的位置,在数学中,xy正数实在第一象限,而在这里,操做的其实是第四象限,都为正数。
4.有意思例子
把上面的x坐标1800改成1800-t*30,咱们能够看到图片跟着时间再向左运动。
若是你热衷技术,喜欢交流,欢迎加入咱们!