[Html] 웹캠 및 이미지 업로드 하여 이미지를 텍스트로 변환하기

밤새·2024년 1월 23일

html에서 웹캠 또는 이미지를 업로드 하여 이미지를 텍스트로 변환하는 법에 대해 알아보도록 하겠습니다!

1. 웹캠 startWebcam 함수

먼저 웹캠에 접근하여 비디오 스트림을 가져온 후 웹페이지의 video 요소에 연결합니다.
만약 웹캠에 접근 중 오류가 발생하면 콘솔에 오류 메시지를 출력합니다.

const startWebcam = () => {
  navigator.mediaDevices
    .getUserMedia({ video: true })
    .then((stream) => {
      video.srcObject = stream;
    })
    .catch((error) => {
      console.error("웹캠에 접근하는 중 오류 발생:", error);
    });
};

navigator.mediaDevices.getUserMedia({ video: true }): navigator.mediaDevices는 브라우저에서 제공하는 미디어 디바이스에 접근하기 위한 API 중 하나입니다. getUserMedia 메서드를 사용하여 미디어 디바이스에 액세스합니다. 이 경우 { video: true }를 사용하여 비디오 스트림에 대한 액세스를 요청하고 있습니다.

.then((stream) => { video.srcObject = stream; }):비디오 스트림을 성공적으로 가져온 경우 실행되는 콜백 함수입니다. stream은 비디오 스트림 객체를 나타냅니다. 이 스트림을 HTML 문서의 <video> 엘리먼트의 srcObject 속성에 할당하여 웹캠에서 영상을 보여주게 됩니다.

2. 이미지 스캔 scanImage 함수

웹캠에서 현재 프레임을 가져와서 캔버스에 그린 후, 그려진 이미지를 processImage 함수에 전달합니다.

const scanImage = () => {
  const canvas = document.createElement("canvas");
  const context = canvas.getContext("2d");
  canvas.width = video.videoWidth;
  canvas.height = video.videoHeight;
  context.drawImage(video, 0, 0, canvas.width, canvas.height);

  processImage(canvas);
};

3. handleImageChange 함수

파일 입력(input type="file")에서 선택된 이미지 파일을 읽어와서, 해당 이미지를 processImage 함수에 전달합니다.
선택된 파일이 없을 경우 오류 메시지를 콘솔에 출력합니다.

const handleImageChange = () => {
  const input = document.getElementById("imageInput");
  const file = input.files[0];

  if (file) {
    const reader = new FileReader();
    reader.onload = function (e) {
      const img = new Image();
      img.src = e.target.result;

      img.onload = function () {
        processImage(img);
      };
    };

    reader.readAsDataURL(file);
  } else {
    console.error("이미지 파일을 선택하세요.");
  }
};

4. 이미지를 텍스트로 변환 processImage 함수

Tesseract.js를 사용하여 이미지에서 텍스트를 추출합니다.
추출된 텍스트는 콘솔에 출력되고, 알림 창을 통해 사용자에게도 표시됩니다.

const processImage = (image) => {
  Tesseract.recognize(image, "eng+jpn", {
    logger: (m) => {
      console.log(m);
    },
  })
    .then(({ data: { text } }) => {
      console.log(text);
      alert("텍스트: " + text);
    })
    .catch((err) => {
      console.error(err);
    });
};

5. DOMContentLoaded 이벤트 리스너

HTML 문서가 로드될 때, startWebcam 함수를 실행하여 웹캠에 접근하고 비디오 스트림을 설정합니다.

document.addEventListener("DOMContentLoaded", startWebcam);

이렇게 각 함수는 웹캠 설정, 이미지 스캔, 파일 업로드 및 이미지 처리 등의 역할을 수행합니다.

전체 코드

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>이미지 텍스트화</title>
    <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/tesseract.js@4/dist/tesseract.min.js"></script>
  </head>

  <body>
    <video id="webcam" autoplay></video>
    <header>
      <img src="../img/x.png" id="x" />
    </header>

    <main>
      <p id="scan-title">사진을 스캔해 주세요</p>
    </main>

    <footer>
      <canvas id="scanCanvas" style="display: none"></canvas>
      <p id="box-title" onclick="scanImage()">스캔하기</p>
      <input type="file" id="imageInput" accept="image/*" />
      <button onclick="handleImageChange()">파일 업로드</button>
    </footer>

    <div id="result"></div>

    <script>
      const video = document.getElementById("webcam");

      const startWebcam = () => {
        navigator.mediaDevices
          .getUserMedia({ video: true })
          .then((stream) => {
            video.srcObject = stream;
          })
          .catch((error) => {
            console.error("웹캠에 접근하는 중 오류 발생:", error);
          });
      };

      const scanImage = () => {
        const canvas = document.createElement("canvas");
        const context = canvas.getContext("2d");
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        context.drawImage(video, 0, 0, canvas.width, canvas.height);

        processImage(canvas);
      };

      const handleImageChange = () => {
        const input = document.getElementById("imageInput");
        const file = input.files[0];

        if (file) {
          const reader = new FileReader();
          reader.onload = function (e) {
            const img = new Image();
            img.src = e.target.result;

            img.onload = function () {
              processImage(img);
            };
          };

          reader.readAsDataURL(file);
        } else {
          console.error("이미지 파일을 선택하세요.");
        }
      };

      const processImage = (image) => {
        Tesseract.recognize(image, "eng+jpn", {
          logger: (m) => {
            console.log(m);
          },
        })
          .then(({ data: { text } }) => {
            console.log(text);
            alert("텍스트: " + text);
          })
          .catch((err) => {
            console.error(err);
          });
      };

      document.addEventListener("DOMContentLoaded", startWebcam);
    </script>
  </body>
</html>

결과


위의 사진을 올려 테스트로 해보도록 하겠습니다!

스캔하기

파일 올리기

확실히 스캔이 정확성이 떨어지긴 하네요..!

profile
프로젝트를 통해 배운 개념이나 겪은 문제점들을 정리하고, 회고록을 작성하며 성장해나가는 곳입니다 😊

0개의 댓글