webRTC初接觸,使用canvas繪制視頻流,並添加顏色濾鏡


效果:(左邊是canvas繪制的視頻,右邊是經過濾鏡處理后的canvas視頻)

 

幾個關鍵點:

requestAnimationFrame 用於重復繪制圖像,形成動態視頻
ctx.drawImage 在canvas中繪制圖像(支持跨域)
getImageData 獲取canvas內的圖像數據
putImageData 圖像數據付給canvas
 
源碼:
html:2個canvas,2個按鈕事件
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>使用canvas繪制視頻流</title>
  <script src="./vue.js"></script>
  <style>
    .canvas {
      width: 300px;
      height: 300px;
      background-color: #000;
      border: 1px solid #000;
    }
  </style>
</head>
<body>
  <div id="app">
    <canvas ref='preview' class="canvas"></canvas>
    <canvas ref='preview2' class="canvas"></canvas>
    <div>
      <button @click="btnplay">播放</button>
      <button @click="btnpause">暫停</button>
    </div>
  </div>
  <script src="3.js"></script>
</body>
</html>

js:

new Vue({
  el: '#app',
  mounted() {
    //canvas ctx對象
    this.ctx = this.$refs.preview.getContext('2d');
    //濾鏡的canvas ctx對象
    this.ctx2 = this.$refs.preview2.getContext('2d');
    //創建video對象
    this.video = document.createElement('video');
    this.video.src = './movie.mp4';
    //canvas寬高
    this.previewWidth = this.$refs.preview.width
    this.previewHeight = this.$refs.preview.height

    //重復執行
    // this.animationFrame()
    requestAnimationFrame(this.animationFrame.bind(this));
  },
  methods: {
    //播放
    btnplay() {
      this.video.play()
    },
    //暫停
    btnpause() {
      this.video.pause()
    },

    //繪制視頻到canvas
    animationFrame() {
      this.ctx.drawImage(this.video, 0, 0, this.previewWidth, this.previewHeight)//繪制圖片 這個是支持跨域的
      /**
       * getImageData/putImageData 只支持同源 不支持跨域
       */
      const imageData = this.ctx.getImageData(0, 0, this.previewWidth, this.previewHeight);//獲取canvas內的圖像數據
      let imageData2 = this.ctx2.createImageData(imageData.width, imageData.height)//創建一個空的canvas圖像數據

      //拷貝canvas1中的數據並改成黑白顏色
      const data = imageData.data
      for (let i = 0; i < data.byteLength; i += 4) {
        let c = Math.floor((data[i] + data[i + 1] + data[i + 2]) / 3)
        imageData2.data[i] = c //r
        imageData2.data[i + 1] = c //g
        imageData2.data[i + 2] = c //b
        imageData2.data[i + 3] = 255 //a
      }

      //改成反轉顏色
      const data2 = imageData2.data
      for (var i = 0; i < data2.length; i += 4) {
        imageData2.data[i] = 255 - data2[i];
        imageData2.data[i + 1] = 255 - data2[i + 1];
        imageData2.data[i + 2] = 255 - data2[i + 2];
        imageData2.data[i + 3] = 255;
      }
      
      this.ctx2.putImageData(imageData2, 0, 0);//圖像數據付給canvas2
      requestAnimationFrame(this.animationFrame.bind(this));
    },
  },
})

 

 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM