18910140161

如何使用Canvas实时处理Video

顺晟科技

2021-06-16 11:02:28

271

结合HTML5下的视频和画布功能,可以实时处理视频数据,为正在播放的视频添加各种视觉效果。本教程演示了如何使用JavaScript代码来实现色度键控

本文中使用的XHTML文档如下。

!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN '

http://www . w3 . org/TR/XHTML 1/DTD/XHTML 1-transitional . DTD '

html xmlns=' http://www . w3 . org/1999/XHTML '

风格

body {

背景:黑色;

color : # CCCCCC;

}

#c2 {

background-image : URL(foo . png);

背景-repeat:不重复;

}

div {

向左浮动:

边框:1px实心# 444444;

padding:10px

margin: 10px

background: # 3B3B3B

}

/style

脚本类型=' text/JavaScript;version=1.8 ' src=' main . js '/脚本

/head

body onload='processor.doLoad()'

差异

视频id=' video ' src=' video . ogv ' controls=' true '/

/div

差异

画布id='c1 '宽度='160 '高度='96'/

画布id='c2 '宽度='160 '高度='96'/

/div

/body

/html

上述代码的关键部分如下:

1.创建了两个画布元素,它们的id分别是c1和c2。C1用于显示当前帧的原始视频,c2用于显示执行色度键控后的视频。C2预装了一张静态图片,将用于替换视频的背景色部分。

2.JavaScript代码从main.js文件导入;这个脚本使用了JavaScript 1.8的特性,所以当导入脚本时,版本在第22行指定。

3.加载网页时,main.js中的processor.doLoad()方法会运行。

JavaScript代码

main.js中的JS代码包含三种方法。

初始化色度键

最初加载XHTML文档时,会调用doLoad()方法。这种方法的作用是为色度键处理代码准备必要的变量,并设置一个事件监听器,我们可以在用户开始播放视频时检测到它。

doLoad:函数(){

this . video=document . getelementbyid(' video ');

this . C1=document . GetElementbyID(' C1 ');

this . CTX 1=this . C1 . GetContext(' 2d ');

this . C2=document . GetElementbyID(' C2 ');

this . CTX 2=this . C2 . GetContext(' 2d ');

让自我=这个;

this . video . addevent listener(' play ',function() {

self . width=self . video . video width/2;

self . height=self . video . video height/2;

self . timercall back();

},false);

},

该代码获取XHTML文档中视频元素和两个画布元素的引用,还获取两个画布的图形上下文的引用。这些将在我们实现色度键控时使用。

AddEventListener()侦听视频元素,并在用户按下视频上的播放按钮时被调用。为了应对用户的回放,这段代码获取视频的宽度和高度,并将其减半(我们在执行色度键控效果时会将视频的大小减半),然后调用timerCallback()方法开始视频捕捉和视觉效果计算。

计时器回调

视频开始播放时(发生“播放”事件时)调用定时器回调函数,然后负责自己的周期调用,实现每帧视频的键控。

timerCallback:函数(){

if (this.video .暂停| | this . video . end){

返回;

}

this . ComputeFrame();

让自我=这个;

setTimeout(函数(){

self . timercall back();

}, 0);

},

回调函数首先检查视频是否在播放;如果没有,回调函数什么也不做,立即返回。

然后调用computeFrame()方法,对当前视频帧执行色度键控。

回调函数做的最后一件事就是调用setTimeout(),以便能尽快再次调用。在实际环境中,您可以根据视频的帧速率来设置呼叫频率。

处理视频帧数据

如下所示的computeFrame()方法实际上负责捕获每一帧的数据,并执行色度键控。

computeFrame:函数(){

this.ctx1.drawImage(this.video,0,0,this.width,this . height);

设frame=this.ctx1.getImageData(0,0,this.width,this . height);

设l=frame . data . length/4;

for(设I=0;I l;i ) {

设r=frame . data[I * 4 0];

设g=frame . data[I * 4 ^ 1];

设b=frame . data[I * 4 ^ 2];

if (g 100 r 100 b 43)

frame . data[I * 4 ^ 3]=0;

}

this.ctx2.putImageData(frame,0,0);

返回;

}

在第二行中,视频帧被复制到个画布ctx1的图形上下文中,并且高度和宽度值被指定为我们之前保存的帧大小的一半。请注意,您可以通过将视频元素传递给绘图上下文的drawImage()方法来绘制当前视频帧。结果是:

第三行代码通过调用个画布上下文的getImageData()方法获取原始图像数据的当前视频帧的副本。它提供了原始的32位像素图像数据,让我们可以操作。第四行代码通过将帧图像数据的总长度除以4来计算图像的总像素数。

第六行代码循环扫描所有像素,获取每个像素的红色、绿色和蓝色值,并将它们与预定义的背景颜色进行比较,这些颜色将被从foo.png导入的背景图像替换。

对于检测为背景的每个像素,将其alpha值替换为零,表示该像素完全透明。结果,最终图像的背景部分是透明的,所以在第13行代码中被绘制到目标的上下文中时,效果是内容叠加在静态背景上。

这在视频回放期间重复进行,以便在一帧之后呈现色度键的特殊效果。

相关文章
我们已经准备好了,你呢?
2024我们与您携手共赢,为您的企业形象保驾护航