WebRTC與CSS濾鏡(CSS filter)

AnRFDev發表於2021-11-29

我們知道了如何使用WebRTC開啟攝像頭,可以擷取視訊幀並且用canvas顯示出來。

本文將濾鏡與視訊結合。給視訊加上一層濾鏡。主要使用到的是filter屬性。

canvas與濾鏡

先來看filter與canvas的使用。先把canvas放好,顯示一張本地的圖片。

<canvas id="sample-canvas" style="width: 358px;height: 100%;"></canvas>

Image把圖片讀進來,然後給canvas來顯示。為了演示方便,canvas的寬高和圖片寬高是一致的。

const sampleCanvas = document.querySelector('#sample-canvas');
var img = new Image();
img.src = 'webrtc-fish.png'; // rustfisher.com pic
img.onload = function () {
  sampleCanvas.getContext('2d').drawImage(img, 0, 0, sampleCanvas.width, sampleCanvas.height);
}

slider

Android中有SeekBar。在這裡我們需要自定義一個slider。這裡也可以根據實際需求,或者使用已有的滑動選擇器。

/* 選擇進度 */
.slider-container {
    width: 100%;
    display: flex;
    justify-content: left;
    align-items: center;
}

/* 滑動選擇器 */
.slider {
    -webkit-appearance: none;
    appearance: none;
    width: 80%;
    height: 100%;
    background: #d3d3d3;
    outline: none;
    opacity: 0.7;
    -webkit-transition: .2s;
    transition: opacity .2s;
}

.slider:hover {
    opacity: 1;
}

.slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 20px;
    height: 20px;
    background: #0c23f7;
    cursor: pointer;
}

.slider::-moz-range-thumb {
    width: 20px;
    height: 20px;
    background: #044caa;
    cursor: pointer;
}

定義幾種濾鏡,準備使用。

  • Blur 效果是糊化
  • Grayscale 效果是灰度
  • Invert 效果是反轉
  • Sepia 效果是深褐色
<select id="filter">
    <option value="none">None</option>
    <option value="blur">Blur</option>
    <option value="grayscale">Grayscale</option>
    <option value="invert">Invert</option>
    <option value="sepia">Sepia</option>
</select>
<div class="slider-container">
    <p id="slide-value" style="width: 10%; height: 100%;"></p>
    <input type="range" min="1" max="100" value="10" class="slider" id="myRange">
</div>

選擇器用了input元素,數值範圍1~100。

canvas+filter

使用濾鏡時,需要改變元素style的filter值。
blur的單位是px。其它可以使用%。把種類和數值拼接成字串,作為filter的值。

const filterSelect = document.querySelector('select#filter');
filterSelect.onchange = function () {
  changeFilter();
};

// 改變濾鏡的值
function changeFilter() {
  var filterValue = "" + filterSelect.value + "(" + slider.value + "%)";
  if (filterSelect.value == "blur") {
    filterValue = "" + filterSelect.value + "(" + slider.value + "px)";
  } else if (filterSelect.value == "none") {
    filterValue = "";
  }
  sampleCanvas.style.filter = filterValue; // 圖片的濾鏡
}

slider.oninput = function () {
  sliderValue.innerHTML = this.value;
  changeFilter();
}

不同的效果預覽如下

效果名 示例圖
原圖 webrtc-fish.png
blur blur.png
gray gray.png
invert invert.png
sepia sepia.png

調整進度選擇數值,可以得到看到效果加強/減弱的樣子。

結合視訊

有了上面的嘗試,我們可以把filter加到video上試試。

首先還是引入webrtc的adapter。

<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

網路不好的同學,也可以下載這個檔案放在你的本地伺服器上。比如

<script src="../js/adapter-latest.js" async></script>

放置video,button和canvas。video預覽攝像頭,canvas用來顯示擷取的影像。

<video playsinline autoplay></video>
<button id="start">開啟攝像頭</button>
<button id="snapshot">擷取</button>
<canvas id="main"></canvas>

和前面的兩篇文章類似,先來開啟攝像頭,然後把攝像頭的流交給video

const snapshotButton = document.querySelector('button#snapshot');
const video = window.video = document.querySelector('video');
const canvas = window.canvas = document.querySelector('canvas#main');
canvas.width = 480;
canvas.height = 360;

function startVideo() {
  navigator.mediaDevices.getUserMedia(constraints).then(gotStream).catch(onError);
}

function gotStream(stream) {
  window.stream = stream;
  video.srcObject = stream;
}

允許瀏覽器使用攝像頭(mac可能還需要多允許一次許可權)。

這次我們要更改video的filter。改變濾鏡的種類時,把濾鏡設定給canvas和video的style。

function changeFilter() {
  var filterValue = "" + filterSelect.value + "(" + slider.value + "%)";
  if (filterSelect.value == "blur") {
    filterValue = "" + filterSelect.value + "(" + slider.value + "px)";
  } else if (filterSelect.value == "none") {
    filterValue = "";
  }
  sampleCanvas.style.filter = filterValue; // 圖片的濾鏡
  canvas.style.filter = filterValue;       // 圖片的濾鏡
  video.style.filter = filterValue;        // 視訊預覽的濾鏡
}

值得注意的是,我們的濾鏡是加在元素上的,並沒有影響視訊和圖片。也就是說這是個附加的效果。

小結

本文將css濾鏡的效果應用在video和canvas上。給視訊和圖片增加了豐富的效果。

預覽

完整預覽請參考 webrtc與css濾鏡示例
原文連結

相關文章