WebRTC與CSS濾鏡(CSS filter)

我們知道了如何使用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濾鏡示例

本文鏈接

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,572評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,071評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,409評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,569評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,360評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,895評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,979評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,123評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,643評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,559評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,742評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,250評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,981評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,363評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,622評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,354評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,707評論 2 370

推薦閱讀更多精彩內容