其实,在JavaCV中除了FFmpegFrameGrabber和FFmpegFrameRecorder之外,还有一个重要的类,那就是FFmpegFrameFilter。

FFmpegFrameFilter封装了ffmpeg滤镜相关操作,使得使用JavaCV进行滤镜操作变成简单,关于ffmpeg滤镜的使用文档可以查看ffmpeg的文档:http://www.ffmpeg.org/ffmpeg-filters.html

简单来说,如果熟悉ffmpeg的滤镜功能,那么使用FFmpegFrameFilter的难度不大,下面通过几个实例演示一下FFmpegFrameFilter的使用方式:

视频缩放

视频缩放使用的滤镜为scale,语法为:scale=width:height[:interl={1|-1}],这里需要注意的是,JavaCV对视频输入的滤镜命名是固定的:

  1. 如果是一路视频,那么输入为in,输出为out
  2. 如果是多路视频,那么输入为n:v,输出为v,这里的n就是第几路视频输入

了解了这一点之后,使用FFmpegFrameFilter就很简单了,下面以视频缩放为例,完整的代码如下:

public class Scale {

  public static void main(String[] args) throws IOException {

    String filterStr = "scale=320:240[out]";
//
FFmpegFrameGrabber stream0 = new FFmpegFrameGrabber(new File("F:/Video/1.mp4"));
stream0.start();
// width=640, height=352
System.out.println("width=" + stream0.getImageWidth() + ", height=" + stream0.getImageHeight());
//
FFmpegFrameFilter filter = new FFmpegFrameFilter(filterStr, stream0.getImageWidth(), stream0.getImageHeight());
filter.start();
//
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(new File("stream0.mp4"), 320, 240);
recorder.setFormat("mp4");
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.start(); int idx = 0;
Frame frame0, frame;
while ((frame0 = stream0.grabImage()) != null) {
filter.push(frame0);
frame = filter.pullImage();
if (frame != null && frame.image != null) {
recorder.record(frame);
}
if (idx++ > 100) {
break;
}
}
recorder.close();
filter.close();
stream0.close();
}
}

滤镜效果:

视频填充

视频填充效果使用的滤镜为pad,语法为:pad=width[:height[:x[:y[:color]]]], FFmpegFrameFilter使用实例跟视频缩放一样,不过滤镜要调整为下面这句:

String filterStr = "pad=700:412:30:30:pink[out]";

另外录制宽高改为原视频宽高:

FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(new File("stream0.mp4"), stream0.getImageWidth(), stream0.getImageHeight());

滤镜效果:

LOGO、字幕

为视频添加LOGO和字幕(滚动)的滤镜相对于前面两个要复杂一点,不过Java代码实现是一样的,采用的滤镜如下:

movie='logo.png'[logo];[in]drawtext=text='我是滚动字幕--HiIT青年':fontfile=simhei.ttf:y=h-line_h-10:x=w-(t-4.5)*w/5.5:fontcolor=white:fontsize=40:shadowx=2:shadowy=2[text];[text][logo]overlay=15:15[out]

滤镜效果:

视频合成

前面提到的都是一路视频操作,对于多路视频的滤镜相对于单路视频有点区别,就是输入有in变成n:v,输出由out变成v, 下面是两路视频合成的完整源码:

public class Hstack {

  public static void main(String[] args) throws IOException {

    String filterStr = "[0:v][1:v]hstack=inputs=2[v]";
//
FFmpegFrameGrabber stream0 = new FFmpegFrameGrabber(new File("F:/Video/1.mp4"));
FFmpegFrameGrabber stream1 = new FFmpegFrameGrabber(new File("F:/Video/1.mp4"));
stream0.start();
stream1.start();
// width=640, height=352
System.out.println("width=" + stream0.getImageWidth() + ", height=" + stream0.getImageHeight());
//
FFmpegFrameFilter filter = new FFmpegFrameFilter(filterStr, stream0.getImageWidth(), stream0.getImageHeight());
filter.setVideoInputs(2);
filter.start();
//
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(new File("stream0.mp4"), stream0.getImageWidth(), stream0.getImageHeight());
recorder.setFormat("mp4");
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.start(); int idx = 0;
Frame frame0, frame1, frame;
while ((frame0 = stream0.grabImage()) != null && (frame1 = stream1.grabImage()) != null) {
filter.push(0, frame0);
filter.push(1, frame1);
frame = filter.pullImage();
if (frame != null && frame.image != null) {
recorder.record(frame);
}
if (idx++ > 200) {
break;
}
}
recorder.close();
filter.close();
stream0.close();
stream1.close();
}
}

滤镜效果:

画中画

画中画滤镜其实跟两路视频合成差不多,不过用的是overlay,语法为:overlay[=x:y[[:rgb={0, 1}]]。下面一个画中画效果的滤镜例子:

String filterStr = "[0:v]scale=iw/2:ih/2[a];[1:v][a]overlay=30:30[v]";

滤镜效果:

NxN N宫格视频

其实不管是NxN,还是1xN,Nx1都可以使用padoverlay组合来实现,下面是2x2四宫格的滤镜:

String filterStr = "[0:v]pad=iw*2:ih*2[a];[a][1:v]overlay=w[b];[b][2:v]overlay=0:h[c];[c][3:v]overlay=w:h[v]";

四路视频输入:

FFmpegFrameGrabber stream0 = new FFmpegFrameGrabber(new File("F:/Video/1.mp4"));
FFmpegFrameGrabber stream1 = new FFmpegFrameGrabber(new File("F:/Video/1.mp4"));
FFmpegFrameGrabber stream2 = new FFmpegFrameGrabber(new File("F:/Video/1.mp4"));
FFmpegFrameGrabber stream3 = new FFmpegFrameGrabber(new File("F:/Video/1.mp4"));

滤镜效果:

文章源码后续整理后将会在公众号发布!

=========================================================



关注公众号,阅读更多文章。

JavaCV 视频滤镜(LOGO、滚动字幕、画中画、NxN宫格)的更多相关文章

  1. FFmpeg中overlay滤镜用法-水印及画中画

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10434209.html 1. overlay技术简介 overlay技术又称视频叠加技术 ...

  2. HTML滚动字幕代码参数详解及Js间隔滚动代码

    html文字滚动代码 <marquee style="WIDTH: 388px; HEIGHT: 200px" scrollamount="2" dire ...

  3. UILabel滚动字幕的实现

    经常需要在应用中显示一段很长的文字,比如天气或者广告等,这时候使用滚动字幕的方式比较方便. 参考文献: [1] YouXianMing, 使用UILabel实现滚动字幕移动效果, 博客园 [2] ht ...

  4. js原生 + jQuery实现页面滚动字幕

    js原生/jQuery实现页面滚动字幕效果 17:45:49 在新闻列表或者文章列表信息等页面中很容易要求实现字幕滚动的效果,以下为简单的实现页面中滚动字幕的效果 1.jQuery实现页面滚动字幕效果 ...

  5. C#-循环滚动字幕,timer,从左至右,从右至左,暂停---ShinePans

    Lable的Left属性是能够更改的,可是 Right属性不能够更改,所以我们能够利用 这个特点做自加 自减运算 using System; using System.Collections.Gene ...

  6. DS控件库 DSLed控件呈现滚动字幕效果

    滚动字幕效果在DSled上可以使用偏移来实现,代码如下 运行效果

  7. 【Cocos2dx 3.3 Lua】滚动字幕

    参考资料:     http://blog.csdn.net/jackystudio/article/details/12991977   1.原理         通过调用update来更新位置达到 ...

  8. Flash和滚动字幕

    flash 1.插入flash     1)<object>             <embed src="路径"></embed>      ...

  9. 使用UILabel实现滚动字幕移动效果

    使用UILabel实现滚动字幕移动效果 这个链接中的代码也实现了这种效果 https://github.com/cbpowell/MarqueeLabel 最终效果如下: 原理如下: 1. 获取文本 ...

随机推荐

  1. java自学第4期——:Scanner类、匿名对象介绍、Random类、ArrayList集合、标准类格式、String类、static静态、Arrays工具类、Math类(1)

    一.Scanner类 1.api简介: 应用程序编程接口 2.Scanner类: 作用:获取键盘输入的数据 位置: java.util.Scanner. 使用:使用成员方法nextInt() 和 ne ...

  2. React高级

    1.React应用 1.1创建应用 创建项目可以使用react脚手架,创建步骤如下 1)安装react脚手架 npm i -g create-react-app 2)创建项目 create-react ...

  3. SpringBoot常见的异常问题

    1. org.mybatis.logging.LoggerFactory Springboot启动报错 Caused by: java.lang.ClassNotFoundException: org ...

  4. SpringBoot(七):SpringBoot中如何使用过滤器(Filter)?

    方式一: 通过注解方式实现: 1.编写一个Servlet3的注解过滤器(和上一章Servlet相似) 贴代码: package com.example.springbootweb.filter; im ...

  5. pytorch(09)transform模块(基础)

    transforms transforms运行机制 torchvision.transforms:常用的图像预处理方法 torchvision.datasets:常用数据及的dataset实现,mni ...

  6. pytorch(00)

    pytorch入门到项目(-) 一.pytorch的环境 本身项目采用win10系统+pycharm+anaconda+cuda. 其中版本为 python 3.7 anaconda 5.3.1 cu ...

  7. MySQL基本指令3 和 索引 、分页

    1视图: -创建  create view 视图名称 as SQL  ps:虚拟 -修改  alter view 视图名称 as SQL -删除  drop view 视图名称 2触发器  3自定义函 ...

  8. C指针与二维数组

    先贴上完整的代码: #include<stdio.h> int main(int argc, char *argv[]){ int a[3] [5]={1,2,3,4,5,6,7,8,9, ...

  9. Bonuses on a Line Gym - 102569B

    题目链接:https://vjudge.net/problem/Gym-102569B 题意:数轴上有N个点,从0出发最多走t步问最多经过几个点. 思路:分开存负数点和整数点,然后枚举每个端点,某个点 ...

  10. springboot集成swagger实战(基础版)

    1. 前言说明 本文主要介绍springboot整合swagger的全过程,从开始的swagger到Knife4j的进阶之路:Knife4j是swagger-bootstarp-ui的升级版,包括一些 ...