- 發布於
Day19: Webcam Fun
- Authors

- Name
- irisjustdoit
- @irisjustdoit
簡介: 如何使用 JavaScript 和 HTML5 的 getUserMedia API 來實現網頁攝影功能。
作品頁面:https://iris1114.github.io/javascript30/19_Webcam-Fun/
HTML
- 包含一個
div容器,內部有控制按鈕、canvas元素、video元素和一個顯示拍攝照片的區域。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Get User Media Code Along!</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="photobooth">
<div class="controls">
<button onClick="takePhoto()">Take Photo</button>
<!--
<div class="rgb">
<label for="rmin">Red Min:</label>
<input type="range" min=0 max=255 name="rmin">
<label for="rmax">Red Max:</label>
<input type="range" min=0 max=255 name="rmax">
<br>
<label for="gmin">Green Min:</label>
<input type="range" min=0 max=255 name="gmin">
<label for="gmax">Green Max:</label>
<input type="range" min=0 max=255 name="gmax">
<br>
<label for="bmin">Blue Min:</label>
<input type="range" min=0 max=255 name="bmin">
<label for="bmax">Blue Max:</label>
<input type="range" min=0 max=255 name="bmax">
</div>
--></div>
<canvas class="photo"></canvas>
<video class="player"></video>
<div class="strip"></div>
</div>
<audio class="snap" src="./snap.mp3" hidden></audio>
<script src="scripts.js"></script>
</body>
</html>
JavaScript
- 使用 JavaScript 來獲取使用者的攝影機影像,並將影像顯示在
video元素中。 - 將
video元素中的影像繪製到canvas元素上,並進行像素處理。 - 拍攝照片並將照片顯示在頁面上。
const video = document.querySelector('.player')
const canvas = document.querySelector('.photo')
const ctx = canvas.getContext('2d')
const strip = document.querySelector('.strip')
const snap = document.querySelector('.snap')
// 獲取使用者的攝影機影像
function getVideo() {
navigator.mediaDevices
.getUserMedia({ video: true, audio: false })
.then((localMediaStream) => {
console.log(localMediaStream)
video.srcObject = localMediaStream
video.play()
})
.catch((err) => {
console.error(`OH NO!!!`, err)
})
}
// 將影像繪製到 canvas 上
function paintToCanvas() {
const width = video.videoWidth
const height = video.videoHeight
canvas.width = width
canvas.height = height
return setInterval(() => {
ctx.drawImage(video, 0, 0, width, height)
let pixels = ctx.getImageData(0, 0, width, height)
// 可以在這裡應用不同的效果
pixels = rgbSplit(pixels)
ctx.putImageData(pixels, 0, 0)
}, 16)
}
// 拍攝照片並顯示在頁面上
function takePhoto() {
// 播放拍照聲音
snap.currentTime = 0
snap.play()
// 從 canvas 中獲取影像數據
const data = canvas.toDataURL('image/jpeg')
const link = document.createElement('a')
link.href = data
link.setAttribute('download', 'handsome')
link.innerHTML = `<img src="${data}" alt="Handsome Man" />`
strip.insertBefore(link, strip.firstChild)
}
// 紅色效果
function redEffect(pixels) {
for (let i = 0; i < pixels.data.length; i += 4) {
pixels.data[i + 0] = pixels.data[i + 0] + 200 // RED
pixels.data[i + 1] = pixels.data[i + 1] - 50 // GREEN
pixels.data[i + 2] = pixels.data[i + 2] * 0.5 // Blue
}
return pixels
}
// RGB 分裂效果
function rgbSplit(pixels) {
for (let i = 0; i < pixels.data.length; i += 4) {
pixels.data[i - 150] = pixels.data[i + 0] // RED
pixels.data[i + 500] = pixels.data[i + 1] // GREEN
pixels.data[i - 550] = pixels.data[i + 2] // Blue
}
return pixels
}
// 綠幕效果
function greenScreen(pixels) {
const levels = {}
document.querySelectorAll('.rgb input').forEach((input) => {
levels[input.name] = input.value
})
for (i = 0; i < pixels.data.length; i = i + 4) {
red = pixels.data[i + 0]
green = pixels.data[i + 1]
blue = pixels.data[i + 2]
alpha = pixels.data[i + 3]
if (
red >= levels.rmin &&
green >= levels.gmin &&
blue >= levels.bmin &&
red <= levels.rmax &&
green <= levels.gmax &&
blue <= levels.bmax
) {
// 將像素透明度設為 0
pixels.data[i + 3] = 0
}
}
return pixels
}
// 啟動攝影機
getVideo()
// 當 video 可以播放時,開始將影像繪製到 canvas 上
video.addEventListener('canplay', paintToCanvas)
Note
- 使用
navigator.mediaDevices.getUserMedia來獲取使用者的攝影機影像。 - 使用
canvas元素來繪製和處理影像。 - 使用
setInterval來定期更新canvas上的影像。 - 提供多種像素處理效果,如紅色效果、RGB 分裂效果和綠幕效果。
