JavaScriptと内蔵カメラでバーコードを読み込む

(1/1)
PHPでISBNコードをASINコードに変換する」では、PHPを使って国際標準図書番号「ISBN」から、Amazonの商品番号「ASIN」に変換するプログラムを紹介した。このプログラムをJavaScriptに移植し、スマホやPCのカメラで本のバーコード(ISBN)を読み込むと自動的にASINに変換することを目指す。

目次

サンプル・プログラムの実行例

JavaScriptと内蔵カメラでバーコードを読み込む
  • 開始]ボタンを押下すると、カメラが撮影を開始する。このプログラムは、インターネットに映像情報は送信しない。
  • カメラを動かして本のバーコード(ISBNコード)を撮影する。
  • バーコード]に認識したバーコードを表示し、[ASINコード]および[Amazon商品]へのリンクを表示する。
  • 終了]ボタンを押下すると、カメラがOFFになる。
  • カメラが無い、もしくはバーコードを認識しない場合は、[ISBN]に変換したいISBNコードを入力し、[変換]ボタンを押下する。
  • バーコードは、多少傾いていても認識するが、画面いっぱいにバーコードを近寄せたときにピントが合うカメラが必要である。

サンプル・プログラムのダウンロード

圧縮ファイルの内容
isbn2asin.html.htmlサンプル・プログラム本体
isbn2asin.html 更新履歴
バージョン 更新日 内容
1.0.0 2023/10/08 初版

バーコードの読取り

 110: <!-- Quagga.jsなどをロード -->
 111: <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
 112: <script src="https://unpkg.com/@ericblade/quagga2@1.7.4/dist/quagga.min.js"></script>
 113: <script src="https://cdn.jsdelivr.net/gh/mtaketani113/jquery-barcode@master/jquery-barcode.js"></script>
 114: <script>

Quagga.js は、JavaScriptだけでバーコード読み取りを可能にするオープンソースのライブラリである。今回は、このライブラリを使用する。ライブラリは unpkg.com から読み込むようにした。
APIについては、公式サイトに英文で説明がある。以下に要点を日本語で記しておく。

プログラムの流れ

JavaScriptと内蔵カメラでバーコードを読み込む

解説:Quagga.js の使い方

 115: //Quagga.js の準備
 116: $('#startButton').click(() => {
 117:     console.log('Quagga.js -- start');
 118: 
 119:     //Quagga.js:初期化
 120:     Quagga.init({
 121:         inputStream: {
 122:             name : 'Live',
 123:             type : 'LiveStream',
 124:             target: document.getElementById('quagga')
 125:         },
 126:         decoder: {
 127:             readers: ['ean_reader']
 128:         }
 129:     }, err =>{
 130:         if(err){
 131:             console.log(err);
 132:             return;
 133:         }
 134:         console.log('Quagga.js -- initialization finished');
 135:         Quagga.start();
 136:     });

Quagga.init(config, callback)

Quagga.js を初期化する。パラメータとエラー・チェックを行い、問題がなければ start メソッドを呼び出してカメラ撮影を開始する。
config‥‥使用ブラウザが inputStream.type に設定している LiveStream をサポートしていない場合、カメラから読み取ることができない。この場合、errパラメータを設定して返す。inputStream.target は、カメラのライブ映像を表示するDOMノードを指定する。
callback関数‥‥前述のerr発生時にはmconsole.logへエラー内容を表示し初期化を終了する。それ以外の時は、Quagga.start() メソッドを実行し、ライブ撮影とバーコード認識を開始する。

 138:     //Quagga.js:処理中
 139:     Quagga.onProcessed(result => {
 140:         if (result == null)                 return;
 141:         if (typeof(result!'object')     return;
 142:         if (result.boxes == undefined)      return;
 143:         const ctx = Quagga.canvas.ctx.overlay;
 144:         const canvas = Quagga.canvas.dom.overlay;
 145:         ctx.clearRect(0, 0, parseInt(canvas.width), parseInt(canvas.height));
 146:         Quagga.ImageDebug.drawPath(result.box, 
 147:             { x: 0, y: 1 }, ctx, { color: 'blue', lineWidth: 5 });

Quagga.onProcessed(callback)

カメラ撮影中に、撮影フレーム毎にコールするメソッドを登録する。引数オブジェクトには、撮影が成功化したかなどの情報が格納されている。
ここでは、撮影が成功したエリアに青い矩形を描く処理を追加してある。

 150:     //Quagga.js:バーコード確定
 151:     Quagga.onDetected(result => {
 152:         console.log(result.codeResult.code);
 153: //      $('#barcode').barcode(result.codeResult.code, 'ean13');     //バーコード表示
 154:         $('#isbn').val(result.codeResult.code);
 155:         dispASIN();
 156:     });

Quagga.onDetected(callback)

バーコードが認識されたときにコールするメソッドを登録する。引数オブジェクトには、認識したバーコードなどの情報が格納されている。
ここでは、認識したコードを id:isbnに表示するとともに、ISBNをASINに変換するユーザー関数 dispASIN を呼び出す。

 150:     //Quagga.js:バーコード確定
 151:     Quagga.onDetected(result => {
 152:         console.log(result.codeResult.code);
 153: //      $('#barcode').barcode(result.codeResult.code, 'ean13');     //バーコード表示
 154:         $('#isbn').val(result.codeResult.code);
 155:         dispASIN();
 156:     });

Quagga.stop()

Quagga.js の処理を終わり、カメラをOFFするときに呼び出す。

解説:ISBNコード

ISBN(International Standard Book Number)は国際標準図書番号とも呼ばれ、書籍を特定するための世界共通の番号体系である。
2006年(平成18年)12月31日までは10進数10桁の番号が用いられていたが、2007年(平成19年)以降には10進数13桁の番号へ移行した。ここでは現行規格を中心に説明する。

ISBNコードは10進数13桁からなり、その内容は下記の通りである。
内容
13-11識別番号(978または979)
10グループ記号(出版国などを表す数字で、日本は4)
9-6出版者記号
5-2書名記号
1チェックデジット
たとえば、『[楽しいPHP入門:ASIN:4844327887:』(クジラ飛行机/インプレスジャパン/2009年11月)という書籍のISBNコードは 9784844327882 である。これを分解すると下記のようになる。
内容
識別番号978
グループ記号4
出版者記号8443
書名記号2788
チェックデジット2
出版者番号 8443 はインプレスコミュニケーションズに与えられた番号である。

チェックデジットはモジュラス10 ウェイト3 という方式である。以下のように計算する。
  1. チェックデジットをのぞく一番左側の桁から順に1,3,1,3を掛けて、それらの和を取る。
  2. 和を10で割った余りを10から引く。ただし10で割って出た余りの下1桁が0の場合は0とする。
これを上記の書籍に適用すると、
9×1+7×3+8×1+4×3+8×1+4×3+4×1+3×3+2×1+7×3+8×1+8×3=138
138%10=8
10-8=2
となり、チェックデジットの 2 を得ることができる。

ちなみに、旧規格(2007年12月31日まで)は10進数10桁であるが、グループ記号、出版者記号、書名記号は現行規格と同じである。チェックデジットの計算方法は異なる(モジュラス11 ウェイト10-2)。

解説:ASINコード

ASIN(Amazon Standard Identification Number)は、Amazon.comが独自に決めた商品番号のことで、書籍についてはISBNの旧規格と同じ番号であった。

ISBNの現行規格についても、識別番号が978であるものについては、桁数10-2は同一である。ただしチェックデジットの計算方法がモジュラス11 ウェイト10-2であるため、最後の1桁の数字が異なる。

モジュラス11 ウェイト10-2方式は、以下のように計算する。
  1. チェックデジットを除いた左側の桁から10,9,8‥‥2を掛けてそれらの和を取る。
  2. 和を11で割って出た余りを11から引く。
前述の『楽しいPHP入門』のASINコードは 4844327887 である。このチェックデジットを求めようとすると、
4×10+8×9+4×8+4×7+3×6+2×5+7×4+8×3+8×2=268
268%11=4
11-4=7
となり、チェックデジットの 7 を得ることができる。

解説:ISBNとASINの関係

9 7 8 ISBNコード 4 8 4 4 3 2 7 8 8 2 4 8 4 4 3 2 7 8 8 7 ASINコード 13 10 5 2 1

解説:ISBNコードをASINコードに変換する

 200: /**
 201:  * ISBNコードをASINコードに変換する
 202:  * @param   string isbn ISBNコード(10進数10桁 or 13桁)
 203:  * @return  string ASINコード(10進数10桁)/FALSE:変換に失敗
 204: */
 205: function isbn2asin(isbn) {
 206:     console.log(isbn);
 207:     //旧ISBNコードの場合はそのまま返す
 208:     const regxOldISBN = /^[0-9]{9}[0-9X]$/i;
 209:     if (isbn.match(regxOldISBN!== null) {
 210:         if (cd11(isbn!== isbn.substring(9, 1))    return false;
 211:         return isbn;
 212:     }
 213: 
 214:     //入力値チェック
 215:     const regxISBN13 = /^[0-9]{13}$/i;
 216:     if (isbn.match(regxISBN13) === null)            return false;
 217:     if (cd10(isbn!isbn.substring(12, 13))       return false;
 218:     const regxISBNhead = /^978/i;
 219:     if (isbn.match(regxISBNhead) === null)          return false;
 220: 
 221:     code = isbn.substring(3, 13);       //10-1桁目を取り出す
 222:     cd = cd11(code);
 223: 
 224:     return isbn.substr(3, 9+ cd;
 225: }

 165: /**
 166:  * チェックデジットの計算(モジュラス11 ウェイト10-2)ASIN用
 167:  * @param   string code 計算するコード(最下位桁がチェックデジット)
 168:  * @return  int チェックデジット
 169: */
 170: function cd11(code) {
 171:     let cd = 0;
 172:     for (let pos = 10pos >2pos--) {
 173:         let n = code.substring(10 - pos, 10 - pos + 1);
 174:         cd +n * pos;
 175:     }
 176:     cd = cd % 11;
 177:     cd = 11 - cd;
 178:     if (cd === 10)  cd = 'X';
 179:     if (cd === 11)  cd = '0';
 180: 
 181:     return cd;
 182: }

 184: /**
 185:  * チェックデジットの計算(モジュラス10 ウェイト3)
 186:  * @param   string code 計算するコード(最下位桁がチェックデジット)
 187:  * @return  int チェックデジット
 188: */
 189: function cd10(code) {
 190:     let cd = 0;
 191:     for (let pos = 13pos >2pos--) {
 192:         let n = code.substring(13 - pos, 13 - pos + 1);
 193:         cd +n * ((pos % 2) == 0 ? 3 : 1);
 194:     }
 195:     cd = cd % 10;
 196: 
 197:     return (cd === 0? 0 : 10 - cd;
 198: }

変換処理自体は、前述のISBNおよびASINの定義にしたがって計算しているだけである。
ただ、入力値のチェックは細かく行っている。

入力値が10進数10桁なら旧ISBNとして処理をする。この際、チェックデジットが合っているかどうか検査する。※10桁の末尾が 'X' の時に正常に動作しませんでした。クロメルさん、ご指摘及び改良方法の提案をありがとうございました(2015年9月20日)。

入力値が10進数13桁なら現行ISBNとして処理をする。この際、チェックデジットがあっているかどうか検査する。また、上位3桁が978以外の場合は変換処理ができないようにしてある。

チェックデジットの計算には、ユーザー関数 cd10, cd11 を用意した。

参考サイト

(この項おわり)
header