ffmepg入门学习六 java把多个图片合成视频,并添加图片水印

1.准备

        使用ffmepg工具,这里就不过多阐述,详细的可查看,我以前的博客。

  准备20张图片,我这里的二十张图片都是加了时间水印的图片(你也可以找不一样的图片,能看出切换的效果就行)。

功能:需要把20张图片合成视频

思路:首先我们存放在本地的图片,一般都是按日期存放的,例如20190515165200.jpg,如果我们要使用ffmepg,合成视频,就需要新创建一个文件夹temp,并把以前的图片复制到temp文件下,注意,一定要满足正则,不然,ffmepeg是无法识别的

注意下面的图片名称格式:都是满足正则表示%2d,因为视频的合成,会根据排序索引一直到最后,如果中间有中断,视频也会终止合成。

这句话如何理解?

我们通过下面的图片发现名称前面的名称是一直+1的,假设我们把05改成22,说明视频到图片04就停止勒,合成的视频指挥包含0-4的图片。

2.多个图片合成视频代码


  
  
  1. package com.qihui.qxj.services.system;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. import org.junit.Test;
  7. public class Test1 {
  8. /**
  9. * 把图片拼接成视频,这里取20张图片,生成10秒的视频
  10. */
  11. @ Test
  12. public void test3( ) {
  13. long startTime =System.currentTimeMillis();
  14. List commend = new ArrayList();
  15. commend. add( "c:/bin/ffmpeg.exe");
  16. //以1fps读入
  17. commend. add( "-r");
  18. commend. add( "4");
  19. //-threads 2 以两个线程进行运行, 加快处理的速度。
  20. commend. add( "-threads");
  21. commend. add( "2");
  22. commend. add( "-f");
  23. commend. add( "image2");
  24. commend. add( "-i");
  25. commend. add( "d:/project/destimg/40/test/%2d.jpg");
  26. commend. add( "-vcodec");
  27. commend. add( "libx264");
  28. //-y 对输出文件进行覆盖
  29. commend. add( "-y");
  30. //-r 5 fps设置为5帧/秒(不同位置有不同含义) %2d标识图片文件的正则
  31. commend. add( "-r");
  32. commend. add( "10");
  33. commend. add( "d:/out.mp4");
  34. start(commend);
  35. long endTime =System.currentTimeMillis();
  36. System. out.println((endTime-startTime));
  37. }
  38. private void start(List commend) {
  39. Process p = null;
  40. try {
  41. ProcessBuilder builder = new ProcessBuilder(commend);
  42. builder.command(commend);
  43. p = builder.start();
  44. p.getOutputStream().close();
  45. doWaitFor(p);
  46. p.destroy();
  47. } catch (Exception e) {
  48. PrintCatchErrorMsg.Print(e, "Part", "getRSTPPicture.catch", "Exception");
  49. p.destroy();
  50. }
  51. }
  52. public static int doWaitFor(Process p) {
  53. InputStream in = null;
  54. InputStream err = null;
  55. int exitValue = -1;
  56. try {
  57. in = p.getInputStream();
  58. err = p.getErrorStream();
  59. boolean finished = false;
  60. while(!finished) {
  61. try {
  62. Character c;
  63. while( in.available() > 0) {
  64. c = new Character(( char) in.read());
  65. System. out.print(c);
  66. }
  67. while(err.available() > 0) {
  68. c = new Character(( char)err.read());
  69. System. out.print(c);
  70. }
  71. exitValue = p.exitValue();
  72. finished = true;
  73. } catch (IllegalThreadStateException var19) {
  74. Thread.currentThread();
  75. Thread.sleep( 500L);
  76. }
  77. }
  78. } catch (Exception var20) {
  79. } finally {
  80. try {
  81. if ( in != null) {
  82. in.close();
  83. }
  84. } catch (IOException var18) {
  85. }
  86. if (err != null) {
  87. try {
  88. err.close();
  89. } catch (IOException var17) {
  90. }
  91. }
  92. }
  93. return exitValue;
  94. }
  95. }

-r在不同位置,产生的意思不一样,-r放在-i前,表示输入,这里我设置的4,表示1秒4帧,20个图片,也就是5秒。

3.多个图片合成视频并打上图片水印


  
  
  1. /**
  2. * 把图片拼接成视频,这里取20张图片,生成10秒的视频
  3. */
  4. @ Test
  5. public void test3( ) {
  6. long startTime =System.currentTimeMillis();
  7. List commend = new ArrayList();
  8. commend. add( "c:/bin/ffmpeg.exe");
  9. //以1fps读入
  10. commend. add( "-r");
  11. commend. add( "4");
  12. //-threads 2 以两个线程进行运行, 加快处理的速度。
  13. commend. add( "-threads");
  14. commend. add( "2");
  15. commend. add( "-f");
  16. commend. add( "image2");
  17. commend. add( "-i");
  18. commend. add( "d:/project/destimg/40/test1/%2d.jpg");
  19. commend. add( "-i");
  20. commend. add( "d:/1557906953.jpg");
  21. commend. add( "-filter_complex");
  22. commend. add(( new StringBuilder( "[1:v]scale=150:150[s];[0:v][s]overlay=")).append( 1800).append( ":").append( 900)
  23. .toString());
  24. commend. add( "-vcodec");
  25. commend. add( "libx264");
  26. //-y 对输出文件进行覆盖
  27. commend. add( "-y");
  28. //-r 5 fps设置为5帧/秒(不同位置有不同含义) %2d标识图片文件的正则
  29. commend. add( "-r");
  30. commend. add( "10");
  31. commend. add( "d:/out.mp4");
  32. start(commend);
  33. long endTime =System.currentTimeMillis();
  34. System. out.println((endTime-startTime));
  35. }

 

     对比上面,多个图片合成视频的代码,视频加上图片水印,多了如下代码:

        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,我们可以看到图片跟着时间再向左运动。

转载自:https://blog.csdn.net/qq_16855077/article/details/90239644

发布了42 篇原创文章 · 获赞 115 · 访问量 1万+

1.准备

猜你喜欢

转载自blog.csdn.net/luoyong_blog/article/details/104497587