主題
利用navigator.mediaDevices.getUserMedia
來取得視訊鏡頭影像,
並透過cavas
來達到拍照與濾鏡的效果。
步驟
Step1. 啟動Local Server
這個練習需要使用到local server,
如果你已經有一個可在本機run起來的server可以直接使用,
或在這層資料夾底下運行npm install
來安裝browser-sync
,
安裝完成後可以透過指令npm start
來啟動localserver(預設port3000),
npm指令需要下載node.js來使用
Step2. 取得影像
透過navigator.mediaDevices.getUserMedia
來取得視訊影像1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17function getVideo() {
// 取得user的視訊裝置,回傳Promise狀態
navigator.mediaDevices.getUserMedia({
video: true,
audio: false
})
// 如果允許則把回傳的MediaStream寫進html的video tag中並播放
.then(localMediaStream => {
/* console.log(localMediaStream); */
video.src = window.URL.createObjectURL(localMediaStream);
video.play();
})
// 當失敗時印出錯誤結果
.catch(err => {
console.error(`ERROR: `, err);
})
}
Step3. 取得視訊資料並輸出在cavas區塊中
1 | function paintToCanavas() { |
Step4. 製作拍照功能!
1 | function takePhoto() { |
參閱:MDN-HTMLCanvasElement.toDataURL()
參閱:MDN-Node.insert Before()
Step5. 濾鏡效果(紅色)
再回到Step3的paintToCanavas()
中新增:1
2
3
4
5
6
7
8
9
10
11
12function paintToCanavas() {
// ...略
return setInterval(() => {
ctx.drawImage(video, 0, 0, width, height);
// 透過getImageData取得當前canvans中所有的像素點(r,g,b,alpha的資訊)
let pixels = ctx.getImageData(0, 0, width, height);
// 製作效果
pixels = redEffect(pixels); // 紅色濾鏡效果
// 置入效果
ctx.putImageData(pixels, 0, 0);
}, 16)
}
並新增一個對應的濾鏡functionredEffect()
1
2
3
4
5
6
7
8
9
10function redEffect(pixels) {
// 透過迴圈將取回的所有像素資料跑一次,i +=4 是因為四個一組(r,g,b,alpha)
for (let i = 0; i < pixels.data.length; i += 4) {
// 下面組合就是單純把R(紅色)增強達到紅色濾鏡的效果
pixels.data[i + 0] = pixels.data[i + 0] + 100;
pixels.data[i + 1] = pixels.data[i + 1] - 50;
pixels.data[i + 2] = pixels.data[i + 2] * 0.5;
}
return pixels;
}
參閱:MDN-CanvasRenderingContext2D.getImageData()
參閱:MDN-putImageData()
其他
另外還有色彩分離與綠幕的濾鏡效果,
基本上程式操作邏輯同Step5的紅色濾鏡效果,
不過色彩的偏移設定我沒什麼顏色概念可以做說明..
所以只能用紅色濾鏡作為說明><..