[JavaScript] 스크립트로 QR코드 스캔하고 데이터 읽기[JavaScript] 스크립트로 QR코드 스캔하고 데이터 읽기

Posted at 2019. 6. 13. 14:28 | Posted in JavaScript & jQuery/JavaScript




※ jsQR의 실제 웹 서비스 사용은 HTTPS접근이 가능한 브라우저를 통해 카메라를 조작할 수 있는 환경에서만 사용이 가능합니다.

   해당 포스팅은 로컬 서버에서 테스트하여 진행 하였으며, 실서버는 보안인증된 HTTPS 접근 가능한 환경에서만 사용이 가능합니다.




GitHub : https://github.com/cozmo/jsQR





■ 웹브라우저용 QR CODE 스캐너 제작 - jsQR 사용





인터넷에 많이 돌아다니는 자료들로 손쉽게 QR코드를 제작할 수 있지만.


보통 이렇게 생산한 QR코드를 읽어어오는 리더기를 제작하는것과 관련된 것은


잘 정리된 포스트를 발견하기 힘들었다.



그렇게 여러가지 방법을 찾다가.


jsQR이란 모듈을을 발견하였고,


이번에 jsQR을 이용하여


제작한 QR코드를 스캔하려하는 예제를 정리해 본다.








#01. jsQR 다운받기



먼저 https://github.com/cozmo/jsQR 페이지에 접속하여 jsQR-master.zip 파일을 을 다운받도록 하자.






다운받은 jsQR-master.zip 파일의 압축을 해제하면


안에 docs 라는 디렉토리가 존재할 것이다.






docs 디렉토리 내에는


index.html 파일과 jsQR.js 파일이 존재하는데


실질적으로 여기서 사용하게 될 파일은 이 jsQR.js 하나이다.








#02. 소스 코드 작성



그냥 index.html을 바로 사용해도 되지만.


아래 코드는 필자가 현재 사용하려고 하는 프로젝트의 성격에 맞게 index.html변경한 코드이다.



<html>

<head>

<meta charset="utf-8">

<title>:: jsQR 테스트 ::</title>

// 다운받은 jsQR.js 를 사용한다.

<script type="text/javascript" src="./jsQR.js"></script>

<style type="text/css">

main {

width:100%;

height:100%;

text-align:center;

}

main > div {

float:left;

width:1%;

height:98%;

}

main > div:first-child {

width:49%;

}

main > div:last-child {

background-color:#D3D3D3;

width:49%;

}


div#output {

background-color:#BDBEBD;

padding-left:10px;

padding-right:10px;

padding-top:10px;

padding-bottom:10px;

}

div#frame {

border:2px solid #005666;

background-color:#FFFFFF;

margin-left:10px;

margin-right:10px;

padding-left:8px;

padding-right:8px;

padding-top:8px;

padding-bottom:8px;

}

div#outputLayer {

text-align:left;

}

canvas {

width:100%;

}

</style>

</head>

<body>

<main>

<div id="test">

<h1>QR 코드 리더</h1>

<div id="output">

<div id="outputMessage">

QR코드를 카메라에 노출시켜 주세요

</div>

    <div id="outputLayer" hidden>

    <span id="outputData"></span>

    </div>

</div>

</div>

<div>&nbsp;</div>

<div>

<h1>스캔</h1>

<div id="frame">

<div id="loadingMessage">

🎥 비디오 스트림에 액세스 할 수 없습니다<br/>웹캠이 활성화되어 있는지 확인하십시오

</div>

<canvas id="canvas"></canvas>

</div>

</div>

</main>

</body>

</html>

<script type="text/javascript">

document.addEventListener("DOMContentLoaded", function() {

var video = document.createElement("video");

var canvasElementdocument.getElementById("canvas");

var canvas = canvasElement.getContext("2d");

var loadingMessagedocument.getElementById("loadingMessage");

var outputContainerdocument.getElementById("output");

var outputMessagedocument.getElementById("outputMessage");

var outputDatadocument.getElementById("outputData");

function drawLine(begin, end, color) {

canvas.beginPath();

canvas.moveTo(begin.x, begin.y);

canvas.lineTo(end.x, end.y);

canvas.lineWidth = 4;

canvas.strokeStyle = color;

canvas.stroke();

                }

    

        // 카메라 사용시

navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment" } }).then(function(stream) {

              video.srcObject = stream;

              video.setAttribute("playsinline", true);      // iOS 사용시 전체 화면을 사용하지 않음을 전달

          video.play();

              requestAnimationFrame(tick);

});


function tick() {

loadingMessage.innerText = "⌛ 스캔 기능을 활성화 중입니다."

if(video.readyState === video.HAVE_ENOUGH_DATA) {

              loadingMessage.hidden = true;

              canvasElement.hidden = false;

              outputContainer.hidden = false;

       

              // 읽어들이는 비디오 화면의 크기

              canvasElement.heightvideo.videoHeight;

                canvasElement.widthvideo.videoWidth;

       

              canvas.drawImage(video, 0, 0, canvasElement.widthcanvasElement.height);

              var imageDatacanvas.getImageData(0, 0, canvasElement.widthcanvasElement.height);


              var code = jsQR(imageData.dataimageData.widthimageData.height, {


                                    inversionAttempts : "dontInvert",

              });

       

                              // QR코드 인식에 성공한 경우

                              if(code) {

            

                                     // 인식한 QR코드의 영역을 감싸는 사용자에게 보여지는 테두리 생성

                                    drawLine(code.location.topLeftCorner, code.location.topRightCorner, "#FF0000");

                                    drawLine(code.location.topRightCorner, code.location.bottomRightCorner, "#FF0000");

                                    drawLine(code.location.bottomRightCorner, code.location.bottomLeftCorner, "#FF0000");

                                    drawLine(code.location.bottomLeftCorner, code.location.topLeftCorner, "#FF0000");


                                    outputMessage.hidden = true;

                                    outputData.parentElement.hidden = false;

         

                                    // QR코드 메시지 출력

                                    outputData.innerHTMLcode.data;

         

                                    // return을 써서 함수를 빠져나가면 QR코드 프로그램이 종료된다.

                                    // return;

                              }

       

                              // QR코드 인식에 실패한 경우 

                              else {


                                    outputMessage.hidden = false;

                                    outputData.parentElement.hidden = true;

                              }

                      }

     

            requestAnimationFrame(tick);

}

});

</script>










#03. QR코드 인식 테스트




먼저 작성한 코드를 브라우저를 통해 실행시켜보자.


해당 기능을 사용할려면 반드시 카메라를 사용할 수 있는 디바이스에서 테스트 해야 한다.






그럼 위와같이 화면이 나타날텐데


먼 브라우저카메라 사용을 허용해 주면


사용이 가능해 질 것이다.






필자가 사용하는 FireFox 브라우저에서는


상단에 카메라를 사용중이라는 버튼이 나타나고,


캔버스(canvas) 영역에 카메라에 비치는 화면이 출력된다.


그럼 인식시킬 QR코드를 화면에 비춰보자.






미리 준비한 QR코드를 화면에 비추어 보았다.


위와 같이 QR코드에 저장된 내용을 읽어들이는 것을 확인 할 수 있다.









  1. 스마일맨
    포스트 글 잘 봤습니다
    한가지 궁금한건 해당 포스트는 pc버전인지요?
    모바일 웹 버전에서도 가능한건지 문의 드립니다
  2. 스마일
    소중한 답변 감사합니다
    블로그 보고 따라 해봤는데 핸드폰 카메라는 안 켜져서 여쭈어 봤습니다 ^^
  3. 갓제로
    저는 navigator.mediaDevices.getUserMedia가 없다고 뜨네요ㅜㅜ
  4. 이용삼
    아이폰에서도 컴퓨터 크롬에서도 삼성핸드폰에서도 비디오 스트림에 엑세스 할수 없다고 하는데요?
  5. 이용삼
    혹시 이것도 https에서만 되는거 아닌가요?
    • 비트박
      2019.11.01 14:24 [Edit/Del]
      예 맞습니다. https에서만 동작을 하는데.
      cafe24 호스팅 같은 경우에는 임의로 https들 붙여서 실행해도 되더군요

      그리고 참고로 아이폰-크롬에서는 동작 하지 않습니다.
  6. pasta
    안녕하세요 혹시 qr코드말고 바코드를 읽을수 있는방법은없을까요?
  7. yomjeeson
    감사합니다. 잘 사용하겠습니다.
  8. 비밀댓글입니다
  9. 도와주세요..
    안녕하세요
    써주신 글 내용으로 잘 보고 공부하여 현재 안드로이드 크롬은 스캔기능 활성화가 안되는 상태,
    하지만 파이어폭스를 설치하여 해보니 스캔기능까지는 활성화를 하였는데요..

    크롬은 여전히 권한허용을 해도 안되는데.. 혹시 안드로이드 크롬에서는 어떻게 활용을 하셨나요???ㅠㅠ

    좋은 글로 도움을 받아서 너무 감사드립니다..
    • 2020.06.17 09:56 신고 [Edit/Del]
      안드로이드 파폭에서 된다면 크롬에서도 카메라 설정만 허용해주면 문제없이 되실겁니다.
      만약 문제가 계속된다면 웨일, 엣지, 오페라등 크로미움기반 다른 브라우저를 설치해보시고
      되신다면 크롬앱을 삭제후 다시 시도해 보심이 좋을것 같습니다.
  10. 도와주세요..
    .. 크롬은 카메라 허용을 해도 진행이 안되네요..

    파이어폭스는 처음에는 권한허용이 떴고, 그 다음 접속시에는 또 한번더 "허용할까요?" 라는 메세지가 뜨는데
    크롬은 권한허용 뒤에 아무런 메세지가 뜨지 않네요..ㅠㅠ

    무슨 차이일지... 웹기반으로 하다보니 그런지 대응이 잘 안되네용..

    사악미소님은 잘 되시는 상황인거죠..?
    jsQR의 버전이 바뀌어서 그런건지;;
    • 2020.06.18 08:43 신고 [Edit/Del]
      말씀드린데로 안드로이드 크롬말고.
      다른 크롬 브라우저에서도 잘 되시는걸까요?

      일단 저는 폰, PC 모든 곳에서 확인을 마친 상태입니다.
      (익스는 포기한 상황입니다.)

      사용하시고 계시는 디바이스 자체 "설정"들어가셔서 그곳에서 브라우저 앱의 카메라 사용권한부터 살펴보아야 할것 같네요.
  11. 도와주세요..
    설정은 아무리봐도 안되고,,,
    이게 크롬이 안드로이드에 기본설치가 되어있어서 그런지 삭제도 안되고,, 재설치는 물론이고;;ㅠㅠ
    다른 직원분들 핸드폰으로도 다 해보았는데 되질 않네요...
    답변 감사합니다. ㅠㅠ
    • 2020.06.18 14:08 신고 [Edit/Del]
      일단 저도 안드로이드 유저라.
      제 안드로이드 기기에서의 테스트는 마쳤던 상황인데, 이유를 모르겠네요.

      도움이 되어 드리지 못했네요.
      어떤걸 만드시려는지는 잘 모르겠지만.
      잘 되시길 바랍니다.
  12. 도와주세요..
    우선 마무리 되었습니다...
    저희 회사에서는 반대네요!

    안드로이드(노트10+ 노트8) - 크롬안됌 / 파이어폭스 됌
    아이폰11 - 크롬됌 / 파이어폭스 안됌

    그동안 답변주셔서 감사합니다~!
    행복한일이 가득하시길 바랍니다 :)
  13. 도움이될지모르겠지만..
    혹시 도움이 될까해서 답글 남깁니다!
    참고로 윈10, 카메라가 있는 노트북에서 진행했습니다.

    [ 올려주신 index.html 그대로 사용했는데 브라우저 콘솔창에 MediaStramError : NotFound 인 경우 해결 ]
    - navigator.mediaDevices.getUserMedia 의 값 ==> video : {facingMode: "user"} // 전면카메라 사용하는 옵션 : 모바일전면카메라, 노트북 카메라인 경우
    - 모바일 후면 카메라 사용시 facingMode: { exact: "environment" } 를 넣어주시면 됩니다.
    (참고 : https://developer.mozilla.org/ko/docs/Web/API/MediaDevices/getUserMedia)

    이렇게 하면 웹(로컬환경)에서는 접근이 되지만 모웹(로컬접근)에서는 카메라가 동작하지 않습니다.
    이때는 https 요청을 하셔야 하는데 로컬에서 ssl 만들어서 was에 적용하면 정상작동합니다. (== 신뢰할수없는 인증서여도 상관없습니다.)
    ("로컬에서 https" 키워드로 검색하시면 잘 나와있습니다.)

    다만, 저같은 경우, 안드로이드에서만 가능하며 ios는 안되는거같..습니다. 제가 못찾는걸수도 있구요! (20.08.20 기준)
    테스트 단말기는 노트 8이고 사용 앱은 기본 인터넷 앱 사용했습니다.

    다른분들은 어떤식으로 접근하셨는지 모르겠지만...저랑 같은 상황인 분들에게 도움이 됐으면 좋겠습니다~
    추가로 좋은 소스 제공해주셔서 감사합니다 :)
    • 2020.08.20 15:58 신고 [Edit/Del]
      도움이 되는 댓글 감사합니다.

      저 또한 테스트를 이 디바이스 저 디바이스 돌아가면서 사용해 보았지만,
      모바일에서 사용한다면 역시 앱을 직접 만드는게 가장 효과적이네요.
  14. 김광욱
    안녕하세요. 먼저 소스를 공개해 주신 점 대단히 감사합니다.
    다름이 아니라
    outputData.innerHTML = code.data;
    해당 부분을
    window.open(outputData.innerHTML, "_self");
    로 변경하였는데. QR을 인식하고 난 다음 QR코드에서 벗어나야지만 window.open이 되고
    계속 QR을 찍고 있으면 페이지가 넘어가지 않는데...
    혹시 이걸 해결할 수 있는 방법이 있나요?
  15. 김광욱
    갤럭시 s10 이상은 동작이 안되는군요..ㅠㅠ
    • 2020.08.25 11:37 신고 [Edit/Del]
      모바일에서 사용은 모바일 앱을 별도로 개발해서 사용하는것이 좋습니다.
      저는 PC에서 웹캠을 연결해서 사용하는 형태를 염두하여 만들었습니다.

Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기