iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 19
0

Day19 Webcam Fun

第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)
}

這樣就可以完成攝影鏡頭的實作,包含畫面特效和轉換成圖片檔案。

Html

<canvas class="photoCan"></canvas>
<video class="playerCam"></video>
<audio class="snapAud" src="http://wesbos.com/demos/photobooth/snap.mp3" hidden></audio>

Javascript

  1. 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.

  2. MediaDevices
    Navigator.mediaDevices提供連結到影音輸入裝置,例如鏡頭和麥克風。

  3. MediaDevices.getUserMedia()
    MediaDevices.getUserMedia()方法允使用者使用媒體裝置產生MediaStream的內容。

navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
  /* use the stream */
})
.catch(function(err) {
  /* handle the error */
});
  1. URL.createObjectURL()
    URL.createObjectURL()用於建立一個帶有URL的 DOMString 以代表參數中所傳入的物件.
    The URL.createObjectURL() static method creates a DOMString containing a URL representing the object given in the parameter. The URL lifetime is tied to the document in the window on which it was created. The new object URL represents the specified File object or Blob object.
bjectURL = URL.createObjectURL(object);
  1. CanvasRenderingContext2D.drawImage()
    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);
  1. CanvasRenderingContext2D.putImageData()
    putImageData()方法將canvas的資料轉換成點陣圖bitmap
    The CanvasRenderingContext2D.putImageData() method of the Canvas 2D API paints data from the given ImageData object onto the bitmap.

  2. 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);
  1. Node.insertBefore()
    insertBefore()在特定元素中插入元素。
var sp1 = document.createElement("span");
var sp2 = document.getElementById("childElement");
var parentDiv = sp2.parentNode;
parentDiv.insertBefore(sp1, sp2); // 插入sp1 至 sp2 之前
tags: video, canvas, navigator

上一篇
Day18 Tally String Times with Reduce
下一篇
Day20 Native Speech Recognition
系列文
JavaScript 30實作心得筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言