HTML5 Video & Canvas 协同使用

· · 科技·工程

本作品采用 CC BY-NC-SA 4.0 授权,本作品包含 CC BY 3.0 的内容(视频),该部分仍适用原始许可,不受本作品的 CC BY-NC-SA 4.0 限制。视频为 Big Buck Bunny。

建议阅读前先学习 Canvas 相关知识。

相关 API

本文使用的相关新 API 如下:

data 数组中,对于第 l 行第 c 列的像素,有 r_{l,c} = D_{4(lw+c)},g_{l,c}=D_{4(lw+c)+1},b=D_{4(lw+c)+2},a=D_{4(lw+c)+3},0\le r,g,b,a \le 255r,g,b,a 分别代表红、绿、蓝和透明度(Alpha值)。

Step 1:准备工作

准备一个标准的 HTML 页面和一个视频。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>HTML Canvas API</title>
        <style>
            /*
              这里会有样式……
             */

             #buffer{
                display: none;
             }
        </style>
    </head>
    <body>
        <div id="content">
            <canvas id="cvs" width="1920" height="1080"></canvas>
            <canvas id="buffer" width="1920" height="1080"></canvas>
            <video id="video" src="video.mp4" width="1920" height="1080" autoplay></video>
        </div>
        <script>
            // 编程区
            const vid = document.getElementById("video");
            const buf = document.getElementById("buffer");
            const output = document.getElementById("cvs")
            let func = time => {
            };
            func();
        </script>
    </body>
</html>

Step 2: 效果实现

我们可以先把视频的每一帧放到一个缓冲区里(buffer,不显示)提取,再进行处理,把处理完的帧写回到输出显示(cvs)中。

func 内添加如下代码:

bufctx.drawImage(vid,0,0); // 读取帧
let data = data.getImageData(0,0,1920,1080); // 帧数据
let len = bufctx.data.length / 4; // 像素数据
for(let i=0;i<len;i++){ // 对于每一个像素……
    let r=data.data[4*i]; // R 值
    let g=data.data[4*i+1]; // G 值 
    let b=data.data[4*i+2]; // B 值
    data[4*i]=data[4*i+1]=data[4*i+2]=(r+g+b)/3; // 灰度效果
}
outctx.putImageData(data,0,0); // 输出

这段代码把每个像素的 RGB 取平均,就得到了灰度的效果。效果如下:

Step 3: 更多效果

还可以做出黑白双色效果,将 data[4*i+1]=data[4*i+1]=data[4*i+2]=(r+g+b)/3 改为 data.data[4*i+1]=data.data[4*i+1]=data.data[4*i+2]=(r+g+b)/3>128 ? 255 : 0;。效果如下:

你还可以做出反色效果,试一试吧!效果应该是这样的:

Ref.