본문 바로가기

개발/JavaScript 30

19. Webcam Fun

반응형

기본 코드

<!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="http://wesbos.com/demos/photobooth/snap.mp3" hidden></audio>

  <script src="scripts.js"></script>

</body>
</html>

목표

웹 API 를 사용하여 웹페이지에서 카메라화면이 출력되고, 그를 통해 사진찍기, 효과주기 등 여러가지를 실행할 수 있도록 해보자.

코드 분석

  1. 사용할 변수를 먼저 지정해 놓는다.

    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');
    
  2. 이벤트리스너에 넣을 함수들을 추가한다.

function getVideo() {
  navigator.mediaDevices.getUserMedia({ video: true, audio: false })
    .then(localMediaStream => {
      console.log(localMediaStream);
      video.src = window.URL.createObjectURL(localMediaStream);
      video.play();
    })
    .catch(err => {
      console.error(`OH NO!!!!`, err);
    });
}

먼저 getVideo()부터 보겠다.
이 안에서 사용되는 내용은 다 웹 API 중 비디오를 가져오는 내용에 해당하는데
navigator.mediaDevices.getUserMedia는 사용자에게 비디오 혹은 오디오에 대한 접근 권한을 얻을 수 있는 메서드이다.
이후에 실행이 안될경우 에러 메시지를 호출하는 방식이다.

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();

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

사진을 찍을 수 있는 함수를 만드는 내용인데, 찍을 때 찰칵소리가 나도록 하고 그 내용을 정렬하도록 하는 내용이다.

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;
}

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) {
      // take it out!
      pixels.data[i + 3] = 0;
    }
  }

  return pixels;
}

효과를 부여해주는 여러가지 메서드이다.

마무리

웹 API를 사용하는 파트라 생각보다 장황한 듯한 내용이 많이 있었다.
끝.

반응형

'개발 > JavaScript 30' 카테고리의 다른 글

21. Geolocation  (0) 2017.04.26
20. Speech Detection  (0) 2017.04.24
18. Adding Up Times with Reduce  (0) 2017.04.24
17. Sort Without Articles  (0) 2017.04.22
16. Mouse move Shadow  (0) 2017.04.22