WebRTC与CSS滤镜(CSS filter)¶
更新日期: 2021-11-29
- 2021-11-29 新建文档
 
我们知道了如何使用WebRTC打开摄像头,可以截取视频帧并且用canvas显示出来。
本文将滤镜与视频结合。给视频加上一层滤镜。主要使用到的是filter属性。
canvas与滤镜¶
先来看filter与canvas的使用。先把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();
}
不同的效果预览如下
| 效果名 | 示例图 | 
|---|---|
| 原图 | ![]()  | 
| blur | ![]()  | 
| gray | ![]()  | 
| invert | ![]()  | 
| sepia | ![]()  | 
调整进度选择数值,可以得到看到效果加强/减弱的样子。
结合视频¶
有了上面的尝试,我们可以把filter加到video上试试。
首先还是引入webrtc的adapter。
网络不好的同学,也可以下载这个文件放在你的本地服务器上。比如
放置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;
}
这次我们要更改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系列
简易预览¶
下面是简易预览。完整预览请参考 webrtc与css滤镜示例
先来选择滤镜,看看左边图片的效果
本站说明
一起在知识的海洋里呛水吧。广告内容与本站无关。如果喜欢本站内容,欢迎投喂作者,谢谢支持服务器。如有疑问和建议,欢迎在下方评论~




