トップへ(mam-mam.net/)

Reading Code39 Barcodes from Camera Video on a Website (Code39 Barcode Reader)

Japanese

Reading CODE39 barcodes from a camera stream in JavaScript using quaggaJS

Execution

When you place a Code39 barcode with start (*) and stop (*) characters in the red frame of the camera view and bring it into focus, it will be read.

Download quaggaJS

Download the ZIP file from the “Download ZIP File” link on the left side of
https://serratus.github.io/quaggaJS/
and extract it.
You will need the files “dist/quagga.min.js” and “src/reader/code_39_reader.js”,
so place them on your web server or a similar environment.

(Example)
/js/quagga.min.js
/js/reader/code_39_reader.js

Source Code

<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=0.1, maximum-scale=4,user-scalable=yes">
<!-- quaggaJSの読み込み -->
<script src="./js/quagga.min.js"></script>
<script src="./js/reader/code_39_reader.js"></script>
<script>
var DetectedCount=0,DetectedCode="";
var video,tmp,tmp_ctx,jan,prev,prev_ctx,w,h,mw,mh,x1,y1;
window.addEventListener('load',function(event){
  video=document.createElement('video');
  video.setAttribute("autoplay","");
  video.setAttribute("muted","");
  video.setAttribute("playsinline","");
  video.onloadedmetadata = function(e){video.play();};
  prev=document.getElementById("preview");
  prev_ctx=prev.getContext("2d", {willReadFrequently:true});
  tmp = document.createElement('canvas');
  tmp_ctx = tmp.getContext("2d", {willReadFrequently:true});
  jan=document.getElementById("jan");

  // A permission dialog for camera access will appear
  navigator.mediaDevices.getUserMedia(
    // Microphone off, camera settings: prefer rear camera, prefer 640×480
    {"audio":false,"video":{"facingMode":"environment","width":{"ideal":640},"height":{"ideal":480}}}
  ).then( // When permission is granted
    function(stream){
      video.srcObject = stream;
      // Scan every 0.5 seconds
      setTimeout(Scan,500,true);
    }
  ).catch( // When permission is denied
    function(err){jan.value+=err+'\n';}
  );

  function Scan(first){
    if(first){
      // Selected width and height
      w=video.videoWidth;
      h=video.videoHeight;
      // Display size on screen
      prev.style.width=(w/2)+"px";
      prev.style.height=(h/2)+"px";
      // Internal canvas size
      prev.setAttribute("width",w);
      prev.setAttribute("height",h);
      mw=w*0.6;
      mh=w*0.2;
      x1=(w-mw)/2;
      y1=(h-mh)/2;
    }
    prev_ctx.drawImage(video,0,0,w,h);
    prev_ctx.beginPath();
    prev_ctx.strokeStyle="rgb(255,0,0)";
    prev_ctx.lineWidth=2;
    prev_ctx.rect(x1,y1,mw,mh);
    prev_ctx.stroke();
    tmp.setAttribute("width",mw);
    tmp.setAttribute("height",mh);
    tmp_ctx.drawImage(prev,x1,y1,mw,mh,0,0,mw,mh);

    tmp.toBlob(function(blob){
      let reader = new FileReader();
      reader.onload=function(){
        let config={
          decoder: {
            readers: ["code_39_reader"],
            multiple: false, // Do not decode multiple barcodes at once
          },
          locator:{patchSize:"large",halfSample:false},
          locate:false,
          src:reader.result,
        };
        Quagga.decodeSingle(config,function(){});
      }
      reader.readAsDataURL(blob);
    });
    setTimeout(Scan,50,false);
  }

  Quagga.onDetected(function (result) {
    // Because misreads are common, treat it as successful only if the same value appears 3 times in a row
    if(DetectedCode==result.codeResult.code){
      DetectedCount++;
    }else{
      DetectedCount=0;
      DetectedCode=result.codeResult.code;
    }
    if(DetectedCount>=3){
      console.log(result.codeResult.code);
      jan.value+=result.codeResult.code+'\n';
      jan.scrollTop=jan.scrollHeight;
      DetectedCode='';
      DetectedCount=0;
    }
  });
});
</script>
</head>
<body>
  <div><canvas id="preview"></canvas></div>
  <textarea id="jan" rows="8" cols="40"></textarea>
</body>
</html>