JavaCV 视频滤镜(LOGO、滚动字幕、画中画、NxN宫格)
其实,在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对视频输入的滤镜命名是固定的:
- 如果是一路视频,那么输入为
in,输出为out - 如果是多路视频,那么输入为
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都可以使用pad和overlay组合来实现,下面是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宫格)的更多相关文章
- FFmpeg中overlay滤镜用法-水印及画中画
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10434209.html 1. overlay技术简介 overlay技术又称视频叠加技术 ...
- HTML滚动字幕代码参数详解及Js间隔滚动代码
html文字滚动代码 <marquee style="WIDTH: 388px; HEIGHT: 200px" scrollamount="2" dire ...
- UILabel滚动字幕的实现
经常需要在应用中显示一段很长的文字,比如天气或者广告等,这时候使用滚动字幕的方式比较方便. 参考文献: [1] YouXianMing, 使用UILabel实现滚动字幕移动效果, 博客园 [2] ht ...
- js原生 + jQuery实现页面滚动字幕
js原生/jQuery实现页面滚动字幕效果 17:45:49 在新闻列表或者文章列表信息等页面中很容易要求实现字幕滚动的效果,以下为简单的实现页面中滚动字幕的效果 1.jQuery实现页面滚动字幕效果 ...
- C#-循环滚动字幕,timer,从左至右,从右至左,暂停---ShinePans
Lable的Left属性是能够更改的,可是 Right属性不能够更改,所以我们能够利用 这个特点做自加 自减运算 using System; using System.Collections.Gene ...
- DS控件库 DSLed控件呈现滚动字幕效果
滚动字幕效果在DSled上可以使用偏移来实现,代码如下 运行效果
- 【Cocos2dx 3.3 Lua】滚动字幕
参考资料: http://blog.csdn.net/jackystudio/article/details/12991977 1.原理 通过调用update来更新位置达到 ...
- Flash和滚动字幕
flash 1.插入flash 1)<object> <embed src="路径"></embed> ...
- 使用UILabel实现滚动字幕移动效果
使用UILabel实现滚动字幕移动效果 这个链接中的代码也实现了这种效果 https://github.com/cbpowell/MarqueeLabel 最终效果如下: 原理如下: 1. 获取文本 ...
随机推荐
- Linux之根目录说明
文件系统 文件系统是操作系统用于明确存储设备(常见的是磁盘,也有基于NAND Flash的固态硬盘)或分区上的文件的方法和数据结构:即在存储设备上组织文件的方法.操作系统中负责管理和存储文件信息的软件 ...
- STM32之SPI通信
SPI总线简介 >SPI总线介绍 SPI接口是Motorola首先提出的全双工三线同步串行外围接口,采用主从模式(Master Slave)架构:支持多slave模式应用,一般仅支持单Maste ...
- linux系统解压命令总结
原文链接:https://www.cnblogs.com/lhm166/articles/6604852.html tar -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追 ...
- 换人!golang面试官:连怎么避免内存逃逸都不知道?
问题 怎么避免内存逃逸? 怎么答 在runtime/stubs.go:133有个函数叫noescape.noescape可以在逃逸分析中隐藏一个指针.让这个指针在逃逸分析中不会被检测为逃逸. // n ...
- 痞子衡嵌入式:盘点国内RISC-V内核MCU厂商(2020年发布产品)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是国内RISC-V内核MCU厂商(2020). 虽然RISC-V风潮已经吹了好几年,但2019年才是其真正进入主流市场的元年,最近国内大量 ...
- virtualbox多个网卡添加(第5-8块儿)
virtualbox多个网卡添加(第5-8块儿) virtualbox默认只能启用4块网卡,如果4块网卡不够则需要通过命令添加.最多可以增加至8块 创建一个文件run.bat,添加如下内容到文件中,然 ...
- 看完我的笔记不懂也会懂----Node.js
Node.js 学习 - 命令行窗口 - 进程与线程 - ECMAScript的缺点 - Node模块化 - Node中的全局对象 - 包 package - NPM包管理器 (Node Packag ...
- CCF(管道清洁):最小费用最大流
管道清洁 201812-5 需要清洁的管道下界为1, 不需要清洁的管道下界为0, 可重复经过的管道上界为正无穷, 不可重复经过的管道上界为1. 这属于无源无汇的有容量下界的最小费用可行流.解决的方法就 ...
- 关于《Android编程权威指南》的MockWalker在模拟器中无法运行的解决方法
1.打开模拟器中的Dev Settings应用. 2.选中Allow mock locations选项. 之后应该就能正常运行了.
- Java 查找算法
1 查找算法介绍 在 java 中,我们常用的查找有四种: 1) 顺序(线性)查找 2) 二分查找/折半查找 3) 插值查找 4) 斐波那契查找 2 线性查找算法 有一个数列: {1,8, 10, ...