Dev/JavaScript30

19. Webcam Fun ( JavaScript30 )

takeU 2021. 7. 10. 19:10
반응형

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-FINISHED.js"></script>

</body>
</html>

 

과정

  1. 요소에 대응되는 상수 생성
  2. 화면에 웹캠 출력
  3. 웹캠의 크기, 위치조정
  4. 사진을 찍고, 저장할 수 있도록 함수 생성
  5. 웹캠에 효과 설정 레인지바 생성, 실행

 

코드 분석

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. 화면에 웹캠 출력

const 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(`error`, err);
 });
}

getViedo함수에 실시간으로 웹캠의 화면이 나올수 있도록 내용을 작성해주고,
에러가 있을때 콘솔에 ‘error’라는 메세지가 실행되도록 함

3. 웹캠의 크기, 위치조정

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

   ctx.putImageData(pixels, 0, 0);
  }, 16);
}

웹캠에서 효과를 적용할 범위를 웹캠의 가로, 세로길이에 맞춰 widthheight에 담고
중앙에 효과가 적용될 새로운 웹캠 화면을 띄워줌

4. 사진을 찍고, 저장할 수 있도록 함수 생성

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

takePhoto()에 버튼을 눌러 사진을 찍으면 찰칵 소리가나도록 소리를 삽입하고,
이미지를 저장할 수 있도록 파일 형식을 설정하고 다운받을수 있도록 함
또한 찍은 이미지가 웹캠 아래에 순서대로 정렬되도록 함

5. 웹캠에 효과 설정 레인지바 생성, 실행

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

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

const 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;
}
getVideo();
video.addEventListener('canplay', paintToCanvas);

이미지에 효과 부여 및 이벤트 실행