WebRTC從攝像頭獲取圖片傳入canvas
前面我們已經能夠利用WebRTC的功能,通過瀏覽器打開攝像頭,并把預覽的影像顯示在video元素中,
接下來我們嘗試從視頻中截取某一幀,顯示在界面上,
html
先準備一下界面,擺上控制元件,下面是關鍵部分的代碼,
<video playsinline autoplay></video>
<button id="showVideo">打開攝像頭</button>
<button id="takeSnapshot">截取</button>
<button id="clearList">清除記錄</button>
<canvas id="mainCanvas"></canvas>
<div id="list" style="display: grid; grid-template-columns: repeat(auto-fill, 100px);
column-gap: 20px; row-gap: 20px;"></div>
- video 用來預覽視頻
- 3個button,分別拿來打開攝像頭,截取圖片和清除記錄
- canvas 用來顯示截取的圖片
- 下面的div是拿來存放多個截取圖片記錄的,給它指定了grid,顯示多個圖片時候比較好看一些
照例,需要引入adapter-latest.js
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
js
準備實作功能,
打開攝像頭并預覽
和之前的打開攝像頭類似,還是要用到getUserMedia方法,拿到視頻流后交給video去播放,
const video = document.querySelector('video');
const constraints = {
audio: false,
video: true
};
// ....
function openCamera(e) {
navigator.mediaDevices.getUserMedia(constraints).then(gotStream).catch(onError);
}
function gotStream(stream) {
window.stream = stream;
video.srcObject = stream;
}
function one rror(error) {
console.log('navigator.MediaDevices.getUserMedia error: ', error.message, error.name);
}
截取圖片
拿到界面中的canvas,先預定一個尺寸(不預定也行),
const mCanvas = window.canvas = document.querySelector('#mainCanvas');
mCanvas.width = 480;
mCanvas.height = 360;
// 開始截取
mCanvas.width = video.videoWidth;
mCanvas.height = video.videoHeight;
mCanvas.getContext('2d').drawImage(video, 0, 0, mCanvas.width, mCanvas.height);
發起截取后,使用getContext獲取到CanvasRenderingContext2D物件,然后呼叫它的drawImage方法,
把video中的視頻幀繪制進去,
除了繪制這一個canvas,我們可以在每次發起(點擊按鈕)的時候創建新的canvas,把它們像相冊一樣展示出來,
const list = document.querySelector('#list'); // 拿來存放多個元素
// 新增1張
var divItem = document.createElement("div");
divItem.style.display = "block";
divItem.width = 100;
divItem.height = divItem.width * video.videoHeight / video.videoWidth; // 計算一下比例
divItem.style.width = divItem.width + "px";
divItem.style.height = divItem.height + "px";
console.log("div item size: ", divItem.width, divItem.height);
var c1 = document.createElement("canvas");
c1.width = divItem.width;
c1.height = divItem.height;
c1.getContext('2d').drawImage(video, 0, 0, mCanvas.width, mCanvas.height, 0, 0, c1.width, c1.height);
divItem.appendChild(c1);
list.appendChild(divItem);
子項的存放方式是div包裹canvas,先用document.createElement("div")創建divItem,
按照視頻的寬高,計算調整divItem的大小,并設定style,
document.createElement("canvas")創建c1,它的寬高設定為前面divItem的寬高,然后把圖片繪制進去,
drawImage時,前面傳入的是視頻(源)的范圍,后面的4個引數是自己的繪制范圍,
這樣一個子項就生成完畢了,添加到我們準備好的串列(div)中,
清除記錄
清除div(list)里的子項,用一個回圈獲取并移除子項,
var child = list.lastElementChild;
while (child) {
list.removeChild(child);
child = list.lastElementChild;
}
小結
打開攝像頭,顯示視頻,把視頻繪制到canvas上,創建多個canvas,做成歷史記錄的效果,
主要利用的還是canvas的繪制方法,繪制的時候注意傳入的引數,能夠指定繪制的邊界,
也就是說只繪制視頻大小中的一部分也是可行的,
示例中用到的關鍵方法
getUserMediagetContextdrawImagecreateElement
預覽
簡易的預覽鏈接
一個軟體工程師的記錄轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/373879.html
標籤:HTML5
上一篇:html完整語法學習
