0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

スマホ+Webブラウザで、QRコードやバーコードを読み取る

0
Last updated at Posted at 2026-09-09

JSでスマホのカメラからQRコード・バーコードを読み取ってみる

この記事は、よくあるスマホのカメラからQRコードやバーコードを読み取るやつをWebブラウザで実装したものです。

カメラの他、保存済の画像も対象にしてみました。

まずは今回作ったデモページを動かしてみる

以下のQRコードは今回作成したページのURLです。
スマートフォンで読み取って、デモページを開いてください。
PCなら、カメラ付きノートPCか、USBカメラを接続すると同様に動きます。

QRコードのURLはこちら
https://ykoba079.github.io/test_prj/smartphone-js/02-camera-code-reader/

スマホで開くと以下の画面が表示されます。
image0.png

画面上部の(QR/バーコード/両方)で、読み取る対象を選択します。

画面下部にある「カメラを起動」ボタンを押すと、カメラにアクセスして処理を開始します。以下のようにカメラの利用許可を求められるので、許可してください。

image1.png

許可すると画面中央にカメラ画像が表示されるので、QRコードやバーコードをカメラに映してみてください。
検出するとコードの位置に枠と番号が付き、画面下部のリストにコードの種類と内容が表示されます。
1枚の画像に複数のコードが写っている場合は10件まで検出します。
以下は、QRとバーコード両方を映したところです。

image10.png

「カメラを起動」ボタンの横にある「写真を選択」ボタンでは、保存しておいた画像ファイルを対象にコードを読み取ります。
イベントでアンケート入力のQRコードを投影されたとき、後でじっくりアンケートページを入力したい時など写真を残しておけばいいので、ちょっと便利かなと思います。
スマホなら写真ライブラリを選択すると、撮影した写真の一覧が表示されるのでそこから写真を選択すると同様にQRコード・バーコードの読み取りをします。
image11.png

JavaScriptでカメラ映像と写真はブラウザ内で処理しています。
写真データをサーバなどへ送信は行いません。

JavaScriptからスマートフォンのカメラを使う

今回はWebブラウザでQRコードを読み取るために、JavaScriptからカメラへアクセスしました。
ブラウザからカメラを利用するには、navigator.mediaDevices.getUserMedia()を使用します。

const stream = await navigator.mediaDevices.getUserMedia({
  audio: false,
  video: {
    facingMode: { ideal: "environment" }
  }
});

video.srcObject = stream;
await video.play();

navigator.mediaDevices.getUserMedia()は、Webブラウザから端末に接続されているカメラやマイクにアクセスして、映像や音声のストリームデータを取得するための機能です。
上記ではビデオを対象にし、facingMode: "environment"は、スマートフォンの背面カメラを優先する指定です。

なぜカメラの利用に許可が必要?

Webページを開いただけでカメラ映像を自由に取得できてしまうと、利用者が知らないうちに周囲の映像を取得されるなど、プライバシーやセキュリティ上の問題につながります。

そのため、ブラウザではカメラやマイクなどのデバイスを利用する際に、利用者へ明示的な許可を求める仕組みになっています。

カメラを停止するときは、以下のように取得したストリームのトラックを停止します。

stream.getTracks().forEach((track) => track.stop());

カメラ映像を画像として取り出す

カメラが返すのは連続した映像です。コードを解析するため、まずは映像の一場面をcanvasへ描画して画像データを取り出します。

context.drawImage(video, 0, 0, canvas.width, canvas.height);

const imageData = context.getImageData(
  0,
  0,
  canvas.width,
  canvas.height
);

まず、drawImage()で、現在のカメラ映像をcanvas要素へ1フレーム分描画します。
第1引数には描画元のvideo要素を指定し、後ろの引数でcanvasの左上 (0, 0) から、canvas.width × canvas.height の大きさに合わせて描画しています。

context.drawImage(video, 0, 0, canvas.width, canvas.height);

続いてgetImageData()で、canvasに描画した画像をピクセルデータとして取得します。

const imageData = context.getImageData(
  0,
  0,
  canvas.width,
  canvas.height
);

ここではcanvas全体を対象にしているため、左上 (0, 0) から幅canvas.width、高さcanvas.heightの範囲を取得しています。

返されるImageDataは、画像の幅・高さと、各ピクセルのRGBA値になります。今回はこのImageDataを、そのままコード読み取りライブラリへ渡して解析しています。

デモではスマートフォンへの負荷を抑えるため、カメラの全フレームを解析するのではなく、一定間隔で画像を取り出しています。また、大きな画像は解析前に縮小しています。

ZXing-WASMでコードを読み取る

コードの解析にはzxing-wasmを使用しました。

zxing-wasmは、ZXing-C++というQRコード・バーコード解析ライブラリをWebブラウザから使えるようにしたもので、Webブラウザ内でQRコードや一次元バーコードを解析できます。

読み取り処理のコア部分は、以下のように記載しています。
readBarcodesに、処理する画像データと、QRコードやCode39などのバーコードの種類を指定しています。

const results = await ZXingWASM.readBarcodes(imageData, {
  formats: [
    "QRCode",
    "EAN13",
    "EAN8",
    "Code128",
    "Code39",
    "ITF"
  ],
  tryRotate: true,
  tryInvert: true,
  maxNumberOfSymbols: 10
});

読み取り結果は配列で返されます。
複数のコードを検出した場合は、それぞれの内容と位置を取得できます。

results.forEach((result) => {
  console.log(result.format);   // QRCode、Code39など
  console.log(result.text);     // 読み取った内容
  console.log(result.position); // 画像内の位置
});

今回のデモでは、次のコード形式を対象にしています。

種類 主な用途例
QRコード URL、テキスト、各種案内
EAN-13/EAN-8 日本の商品で使われるJANコード
Code 39/128 製造・物流の管理ラベル
ITF/ITF-14 段ボールなどの集合包装

補足:一次元バーコードとQRコードの読み取りやすさの差

一次元バーコードは、線の太さや間隔を読み取ります。(例えばJANコードは太さが4種類あり、この太さを区別する必要があります)
このため、ピンぼけや解像度不足、斜めに撮影すると線の太さを誤認して読み取りに失敗しやすい傾向があります。

一方、QRコードは位置検出用の目印や誤り訂正の仕組みを持つため、多少の汚れや欠損に対応できるよう設計されています。

使用ライブラリとライセンス

使用ライブラリのライセンスは次のとおりです。

ソフトウェア ライセンス 再配布時の主な対応
zxing-wasm MIT License 著作権表示とライセンス文を含める
ZXing-C++/ZXingWasm.cpp Apache License 2.0 ライセンス文を含める。NOTICEがある場合はその内容も確認する
Zint由来部分 BSD 3-Clause License 著作権表示・ライセンス条件・免責条項を含める

今回は次のように、リポジトリのライセンス情報に記載しました。

カメラだけでなく写真からも読み取る

スマートフォンでも、ファイル選択用のinputから写真ライブラリを開けます。(スマホでの挙動を最近知りましたw)

<input type="file" accept="image/*">

イベントのアンケート入力用のQRコード等、その場で入力する時間が無い場合はコードの写真を撮っておいて、後から処理する、という事や、PDFやFAXで受け取った注文票にコードがある場合も利用できそうですね。
画像全体に対してコードが小さい(書類の下に小さくあるとか)と読み込みに失敗しやすくなるので、その場合は別途、ユーザーに読み取り範囲をタップして指定してもらったり、帳票のレイアウトが決まっているならコードのある範囲だけを切り出したりしてから、ライブラリへ渡すといった工夫が必要になります。

1件ずつしか読めないわけではない

スマートフォンの標準的なQRコード読み取り機能は、カメラに映した1つのコードを素早く読み取り、その場でURLを開くような用途に向いています。

一方で、1枚の書類や写真に複数のコードが含まれている場合もあります。

今回のデモでは画像全体を解析し、複数のQRコードやバーコードを一度に検出するようにしているので、検出した位置情報を使えば、帳票の並びに沿ったコード一覧を作ることもできそうですね。

例えば、以下のようなケースでしょうか。

製造・インフラ・設備点検

  • 部品ラベルから部品番号を読み取る
  • 作業指示書と対象部品の組み合わせを確認する
  • 設備の管理番号から点検記録を呼び出す

Codex 画像 2026年9月10日 01_30_52.png

物流

  • 荷札や梱包箱のコードを読み取り、入出庫対象の確認に利用する
  • 複数のラベルを写真に撮り、後からまとめて確認する

オフィス・金融

  • 貸与端末や備品の資産番号を確認する
  • 郵送物や帳票の仕分けを補助する

まとめ

今回は、スマートフォンのカメラと写真をJavaScriptから利用し、QRコードとバーコードを読み取ってみました。

専用のバーコードリーダーの方が速度や精度はよいですが、ちょっと確認してみたい時や、普段バーコードリーダーを持ち歩いていない場面にもすぐ対応できる点がやはり便利かと思います。

お試しを!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?