• WebRTC与CSS滤镜(CSS filter)


    我们知道了如何使用WebRTC打开摄像头,可以截取视频帧并且用canvas显示出来。

    本文将滤镜与视频结合。给视频加上一层滤镜。主要使用到的是filter属性。

    canvas与滤镜

    先来看filter与canvas的使用。先把canvas放好,显示一张本地的图片。

    <canvas id="sample-canvas" style=" 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 {
         100%;
        display: flex;
        justify-content: left;
        align-items: center;
    }
    
    /* 滑动选择器 */
    .slider {
        -webkit-appearance: none;
        appearance: none;
         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;
         20px;
        height: 20px;
        background: #0c23f7;
        cursor: pointer;
    }
    
    .slider::-moz-range-thumb {
         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=" 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滤镜示例
    原文链接

    一个软件工程师的记录
  • 相关阅读:
    js调用.net后台事件,和后台调用前台等方法以及js调用服务器控件的方法
    .net反编译工具reflector5.0 的介绍及使用
    box flex 弹性盒模型
    TransactionScope使用说明
    您的主机中的软件中止了一个已建立的连接。
    Android中Handler
    转载 JavaScript的24条实用建议
    repeater中的checkbox 的方法以及datalist中放了一个按牛!为什么我按该按牛时候不能触发ItemCommand事件的主要原因
    asp.net cookies用法
    常用的数据分页技术总结
  • 原文地址:https://www.cnblogs.com/rustfisher/p/15618838.html
Copyright © 2020-2023  润新知