QuaggaJSを使用したブラウザでの二次元バーコードスキャン

QuaggaJSとは

JavaScriptで書かれたバーコードスキャナ。

EAN, CODE 128, CODE 39, EAN 8, UPC-A, UPC-C, I2of5, 2of5, CODE 93, CODABARといった様々なタイプのバーコードのリアルタイムローカライズとデコードをサポートしています。

一般的な日本の商品に付いているバーコードはEANおよびEAN 8を使用しています。

QuaggaJSのインストール

npmでインストールする場合は以下の通り。

npm i -D quagga

あるいは以下のURLのJavaScriptを利用する。

https://serratus.github.io/quaggaJS/examples/js/quagga.min.js

インストールしたらconsole.log(Quagga)が表示されるか確認してみてください。

QuaggaJSの使い方

「カメラでバーコードを読み込む」というボタンを押したらカメラが起動してバーコードを写すとinputタグにバーコードの番号が入力されるというサンプルを作成しながら説明します。

QuaggaJSを使用したブラウザでの二次元バーコードスキャン

HTMLの準備

まず入力欄とボタンが必要なのでHTML内に以下のコードを追加してください。

<h1>バーコード読み込みサンプル</h1>
<input id="code" type="text">
<button id="btn">カメラでバーコードを読み込む</button>
<div id="modal" class="modal">
  <div id="interactive" class="viewport"></div>
  <p class="text">カメラにバーコードを写してください。</p>
</div>

カメラ起動後の画面はモーダルです。

<div id="interactive" class="viewport"></div>のidとclassはQuaggaJSで使用されるidとclass名なので変更しないでください。

CSSの準備

CSSについては特筆することはない。

モーダル部分はボタンを押すまではdisplay: noneで非表示にしてあります。

* {
  box-sizing: border-box;
}
html,
body {
  height: 100%;
}
h1 {
  font-size: 1rem;
}
input {
  width: 300px;
  margin-bottom: 1rem;
  font-size: 2rem;
}
video {
  width: 100%;
}
.modal {
  display: none;
  overflow: hidden;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.8);
}
.text {
  position: fixed;
  bottom: 1rem;
  left: 0;
  width: 100%;
  margin-top: 1rem;
  color: #fff;
  text-align: center;
}

JavaScriptの準備

JavaScriptはまずボタンをクリックした際にモーダルを開く処理を書く。

const btn = document.getElementById('btn');
const modal = document.getElementById('modal');

btn.addEventListener('click', () => {
  modal.style.display = 'block';
  document.body.style.overflow = 'hidden';
});

次にQuagga.initで初期設定を記述する。

カメラを起動してリアルタイムでバーコードを読み込むので、inputStreamを「type: 'LiveStream'」に設定。

decoderのreadersにはformat: 'ean_reader'とconfig: {}を設定します。

エラーが検出されない場合はカメラを起動してQuagga.start()を実行します。

const btn = document.getElementById('btn');
const modal = document.getElementById('modal');

btn.addEventListener('click', () => {
  modal.style.display = 'block';
  document.body.style.overflow = 'hidden';
  Quagga.init(
    {
      inputStream: {
        type: 'LiveStream',
        constraints: {
          width: window.innerWidth
        },
      },
      decoder: {
        readers: [
          {
            format: 'ean_reader',
            config: {},
          },
        ],
      },
    },
    (err) => {
      if (!err) {
        Quagga.start();
      } else {
        modal.style.display = 'none';
        document.body.style.overflow = '';
        Quagga.stop();
        alert(
          'この機能を利用するには\nブラウザのカメラ利用を許可してください。'
        );
      }
    }
  );
});

続いてQuagga.start();を実行したあとのバーコードの読み込み処理を追加します。

Quagga.onDetected(result)でバーコード検出後の値を引数で返します。

あとはinputの入力欄にバーコードの番号を入れてモーダルを非表示にしたあとQuagga.stop()で停止させれば完成です。

Quagga.onDetected((result) => {
  const code = result.codeResult.code;
  document.getElementById('code').value = code;
  modal.style.display = 'none';
  document.body.style.overflow = '';
  Quagga.stop();
});

バーコード読み込みサンプル

QuaggaJSはバーコードを読み取っても撮影する角度によっては間違った値を返すことがある点に注意してください。

日本の商品であれば先頭に国コードの「45」または「49」が付くので正規表現で絞り込めば検出精度が向上します。

Quagga.onDetected((result) => {
  const code = result.codeResult.code;
  if (/^4[5|9]/.test(code)) {
    document.getElementById('code').value = code;
    modal.style.display = 'none';
    document.body.style.overflow = '';
    Quagga.stop();
  }
});

バーコード読み込みサンプル(国コード45および49のみ)