iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 20
0

今天的實作有點兒難度,是要用到你的視訊鏡頭,做出一個能夠製造特效、拍照及下載的功能,介面如下:
Imgur
每拍一張照,下方就會多一張照片,點選即可下載該張照片。
但由於視訊鏡頭牽涉到安全性問題,需要用到https,這邊就不提供實作範例。有興趣的同學可直接下載教材試用。

邏輯流程

  1. 開啟鏡頭
  2. 將畫面放入畫布
  3. 拍照功能
  4. 下載功能
  5. 特效功能

課程重點

  1. 啟動視訊鏡頭:方法如下
    navigator.mediaDevices.getUserMedia({ video: true, audio: false })
        .then(localMediaStream => {
          video.srcObject = localMediaStream;
          video.play();
        })
    
  2. 將畫面放入畫布:方法如下
    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);
        }, 16);
    }
    
    將視訊鏡頭的解析度同樣設定給畫布,而下方的setInterval()是為了讓畫布能夠和鏡頭同步(若沒設定的話畫布就不會動),根據可負荷效能來調整每多少毫秒要更新畫面一次。
  3. 拍照與下載功能:
    function takePhoto() {
      // played the sound
      snap.currentTime = 0;
      snap.play();
    
      // take the data out of the 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.firsChild);
    }
    
    前面snap部分是播放相機快門聲。後面是產生一個下載連結,並以相片的方式呈現。最後insertBefore()是為了將每次新拍的照片都出現在列表最前面。
  4. 特效功能:特效的部分可以隨個人喜好調整,這邊舉前面圖片特效的例子,將紅藍綠拆開的效果。
    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;
    }
    
    首先要做特效必須先將畫布的像素抓出來let pixels = ctx.getImageData(0, 0, width, height),調整完後再放回去ctx.putImageData(pixels, 0, 0);。而pixels其實是超大一串由紅、綠、藍、透明度四個數輪流組成的Array(影像每個像素是由RGB組成,每個顏色範圍為0~255,透明度則是0~1)。這個特效的概念很簡單,就只是分別給予紅綠藍不同的差值,例如上面例子就是將迴圈目前像素的紅光值填進前面150個像素位置,把綠光值填近後面第500個像素位置,藍光值填進前面550個像素位置。所以三個顏色就會產生平移的偏差,造成圖片中的效果。

上一篇
第十八堂 - Adding Up Times with Reduce
下一篇
第二十堂 - Speech Detection
系列文
JS30自我學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

我要留言

立即登入留言