【你不知道的canvas】之更换绿屏视频背景

共 5263字,需浏览 11分钟

 ·

2021-05-22 23:43

点击上方 前端瓶子君,关注公众号

回复算法,加入前端编程面试算法每日一题群

源:JenK
https://segmentfault.com/a/1190000039975476

canvas Api 简单介绍

githubPage(gitee最近整治giteepage,先用github的了,如果打不开就下载源码本地起静态服务查看)https://developer.mozilla.org/zh-CN/docs/Learn/HTML/Multimedia_and_embedding/Video_and_audio_content

实现思路

视频==>视频截图==>处理绿色像素为透明==>贴图至背景图上方
将视频进行截图,再将视频中像素为绿色的像素块变为透明
再将处理好图片放在事先准备好的背景图上方

实现

1.准备视频以及画布

<body onload="processor.doLoad()">
  <div>
    <video id="video" src="./q.mp4" width="350" controls="true"></video>
  </div>

  <div>
    <!-- 视频截图 -->
    <canvas id="c1" width="260" height="190"></canvas>
    <!-- 处理绿色像素为透明 -->
    <canvas id="c2" width="260" height="190"></canvas>
    <!-- 贴图至背景图上方 -->
    <canvas id="c3" width="260" height="190"></canvas>
  </div>

</body>

2.添加视频播放监听

doLoad: function doLoad({
      this.video = document.getElementById("video");
      this.c1 = document.getElementById("c1");
      this.ctx1 = this.c1.getContext("2d");
      this.c2 = document.getElementById("c2");
      this.ctx2 = this.c2.getContext("2d");
      this.c3 = document.getElementById("c3");
      this.ctx3 = this.c3.getContext("2d");
      let self = this;
      this.video.addEventListener(
        "play",
        function({
          self.width = self.video.videoWidth / 5;
          self.height = self.video.videoHeight / 3;
          self.timerCallback();
        },
        false
      );
}

3.添加计时器

视频播放后进行调用,进行每一帧的截图抓取

timerCallback: function timerCallback({
  if (this.video.paused || this.video.ended) {
        return;
  }
  this.computeFrame();
      let self = this;
      setTimeout(function ({
        self.timerCallback();
  }, 0);
}

4.进行视频帧操作

将绿色背景设置为透明,并贴图至自定义背景图上

computeFrame: function computeFrame({
      this.ctx1.drawImage(this.video, 00this.width, this.height);
      let frame = this.ctx1.getImageData(00this.width, this.height);
      let l = frame.data.length / 4;
    
      for (let i = 0; i < l; i++) {
        let r = frame.data[i * 4 + 0];
        let g = frame.data[i * 4 + 1];
        let b = frame.data[i * 4 + 2];
        //rgb(8 204 4)
        if (r > 4 && g > 100 && b < 100) {
          frame.data[i * 4 + 3] = 0;
        }
      }
      this.ctx2.putImageData(frame, 00);
      this.ctx3.putImageData(frame, 00);
      return;
}

5.微调

//rgb(8 204 4)
        绿色的视频颜色不纯,不是一直都是rgb(8 204 4),所以进行了简单的微调。。
if (r > 4 && g > 100 && b < 100) {
  frame.data[i * 4 + 3] = 0;
}

最后

欢迎关注【前端瓶子君】✿✿ヽ(°▽°)ノ✿
回复「算法」,加入前端编程源码算法群,每日一道面试题(工作日),第二天瓶子君都会很认真的解答哟!
回复「交流」,吹吹水、聊聊技术、吐吐槽!
回复「阅读」,每日刷刷高质量好文!
如果这篇文章对你有帮助,在看」是最大的支持
》》面试官也在看的算法资料《《
“在看和转发”就是最大的支持


浏览 22
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报