WebAssembly 出来已经很久了,但是一直都没有实践过,实在是不应该,所以就趁这次国庆假期浅学一下吧。毛主席说过,“实践是检验真理的唯一标准”,所以我们今天就实现一个“视频实时滤镜效果”的功能。可直接看代码。
我们知道,视频其实是由一幅幅的图像组成的,每一幅图像称为一“帧”。所以,我们可以通过 canvas 来获取视频的图像数据,对图像数据进行处理完后再绘制到 canvas 上去,然后通过 requestAnimationFrame 让图像动起来,代码大致如下:
function draw() {...// 将当前视频播放的“帧”绘制到 canvas 上面context2D.drawImage(video,0,0,video.videoWidth,video.videoHeight,0,0,canvas.width,canvas.height)// 得到图像数据const pixels = context2D.getImageData(0, 0, canvas.width, canvas.height)// 处理const newData = filter(...)// 修改 canvas 上的内容pixels.data.set(newData)context2D.putImageData(pixels, 0, 0)...requestAnimationFrame(draw)
}
为了衡量我们的滤镜算法效率,我们需要计算图像的帧率(FPS),大致思想是先取最近 20 次 draw 函数的平均执行时间,然后用其除 1000:
function draw() {const timeStart = performance.now()...let timeUsed = performance.now() - timeStartarr.push(timeUsed)calcFPS(arr)requestAnimationFrame(draw)
}
function calcFPS(arr: number[]) {const n = 20if (arr.length > n) {arr.shift()} else {return NaN}let averageTime =arr.reduce((pre, i