第19天是網頁使用視訊鏡頭來抓取視訊畫面,讓視訊畫面呈現在網頁上,並可以加入畫面特效,還可將網頁影像轉換成影像檔案。
首先畫面開啟錄影鏡頭功能,使用navigator.mediaDevices.getUserMedia來開啟鏡頭功能,並取得鏡頭錄製畫面的影像,將影像透過video元素播放。
function getVideo() {
navigator.mediaDevices.getUserMedia({ video: true, audio: false })
.then( localMediaStream =>{
video.src = window.URL.createObjectURL(localMediaStream)
video.play()
})
.catch(err =>{
console.error('Error', err)
})
}
之後將影像畫面結果畫上canvas元素,使用ctx.getImageData()來讓video的影像資料畫到canvas上,透過setInterval()讓其固定秒數觸發繪畫到canvas元素。設定為16毫秒就重新繪畫一次。
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.data = mirror(pixels, width, height)
// 讓畫面產生產生鏡像畫面
pixels = redEffect(pixels)
// pixels值 紅色調大
pixels = rgbSplit(pixels)
ctx.globalAlpha = 0.1
// 顏色 位置對調
pixels = greenScreen(pixels)
//
ctx.putImageData(pixels, 0, 0);
}, 16)
在畫到canvas的過程中,可以透過ctx.getImageData()的方式來取得canvas上的像素值,每一個像素值共有四個值為(RGBA),之後可對取得的像素值做特定的效果變化。
之後製作類似拍照的功能,首先建立一個click事件,在click事件中包含事件觸發時產生拍攝的音效,以及將canvas中的資料成點陣圖的連結,將連結轉換成a元素,並a元素插入到strip元素的第一個子元素之前。
function takePhoto(){
// palyed the sound
snap.currentTime=0
snap.play()
// take data out of canvas
const data = canvas.toDataURL('image/jpeg', 1.0)
const link = document.createElement('a')
link.href = data
link.setAttribute('Download', 'doenloadName')
link.innerHTML=`<img src=${data} alt='canvase ' >`
strip.insertBefore(link, strip.firstChild)
}
這樣就可以完成攝影鏡頭的實作,包含畫面特效和轉換成圖片檔案。
<canvas class="photoCan"></canvas>
<video class="playerCam"></video>
<audio class="snapAud" src="http://wesbos.com/demos/photobooth/snap.mp3" hidden></audio>
navigator
The Navigator interface represents the state and the identity of the user agent. It allows scripts to query it and to register themselves to carry on some activities.
MediaDevicesNavigator.mediaDevices提供連結到影音輸入裝置,例如鏡頭和麥克風。
MediaDevices.getUserMedia()MediaDevices.getUserMedia()方法允使用者使用媒體裝置產生MediaStream的內容。
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
/* use the stream */
})
.catch(function(err) {
/* handle the error */
});
URL.createObjectURL()用於建立一個帶有URL的 DOMString 以代表參數中所傳入的物件.bjectURL = URL.createObjectURL(object);
drawImage()方法提供Canvas能夠畫上image。var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var image = document.getElementById('source');
ctx.drawImage(image, 33, 71, 104, 124, 21, 20, 87, 104);
CanvasRenderingContext2D.putImageData()putImageData()方法將canvas的資料轉換成點陣圖bitmap。
The CanvasRenderingContext2D.putImageData() method of the Canvas 2D API paints data from the given ImageData object onto the bitmap.
HTMLCanvasElement.toDataURL()URL.createObjectURL()用於建立一個帶有URL的 DOMString 以代表參數中所傳入的物件. 該URL的生命週期與創造它的window中的 document一致. 這個新的物件URL 代表了所指定的 File 物件 或是 Blob 物件.toDataURL()方法是回傳代表影像格式資料的
The HTMLCanvasElement.toDataURL() method returns a data URI containing a representation of the image in the format specified by the type parameter (defaults to PNG). The returned image is in a resolution of 96 dpi.
var fullQuality = canvas.toDataURL('image/jpeg', 1.0);
// data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ...9oADAMBAAIRAxEAPwD/AD/6AP/Z"
var mediumQuality = canvas.toDataURL('image/jpeg', 0.5);
var lowQuality = canvas.toDataURL('image/jpeg', 0.1);
insertBefore()在特定元素中插入元素。var sp1 = document.createElement("span");
var sp2 = document.getElementById("childElement");
var parentDiv = sp2.parentNode;
parentDiv.insertBefore(sp1, sp2); // 插入sp1 至 sp2 之前
video, canvas, navigator