目次
サンプル・プログラムの実行例
- [開始]ボタンを押下すると、カメラが撮影を開始する。このプログラムは、インターネットに映像情報は送信しない。
- カメラを動かして本のバーコード(ISBNコード)を撮影する。
- [バーコード]に認識したバーコードを表示し、[ASINコード]および[Amazon商品]へのリンクを表示する。
- [終了]ボタンを押下すると、カメラがOFFになる。
- カメラが無い、もしくはバーコードを認識しない場合は、[ISBN]に変換したいISBNコードを入力し、[変換]ボタンを押下する。
- バーコードは、多少傾いていても認識するが、画面いっぱいにバーコードを近寄せたときにピントが合うカメラが必要である。
サンプル・プログラムのダウンロード
isbn2asin.html.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 の使い方
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.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 });
カメラ撮影中に、撮影フレーム毎にコールするメソッドを登録する。引数オブジェクトには、撮影が成功化したかなどの情報が格納されている。
ここでは、撮影が成功したエリアに青い矩形を描く処理を追加してある。
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: });
バーコードが認識されたときにコールするメソッドを登録する。引数オブジェクトには、認識したバーコードなどの情報が格納されている。
ここでは、認識したコードを 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.js の処理を終わり、カメラをOFFするときに呼び出す。
解説:ISBNコード
2006年(平成18年)12月31日までは10進数10桁の番号が用いられていたが、2007年(平成19年)以降には10進数13桁の番号へ移行した。ここでは現行規格を中心に説明する。
ISBNコードは10進数13桁からなり、その内容は下記の通りである。
桁 | 内容 |
---|---|
13-11 | 識別番号(978または979) |
10 | グループ記号(出版国などを表す数字で、日本は4) |
9-6 | 出版者記号 |
5-2 | 書名記号 |
1 | チェックデジット |
内容 | 値 |
---|---|
識別番号 | 978 |
グループ記号 | 4 |
出版者記号 | 8443 |
書名記号 | 2788 |
チェックデジット | 2 |
チェックデジットはモジュラス10 ウェイト3 という方式である。以下のように計算する。
- チェックデジットをのぞく一番左側の桁から順に1,3,1,3を掛けて、それらの和を取る。
- 和を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となり、チェックデジットの 2 を得ることができる。
138%10=8
10-8=2
ちなみに、旧規格(2007年12月31日まで)は10進数10桁であるが、グループ記号、出版者記号、書名記号は現行規格と同じである。チェックデジットの計算方法は異なる(モジュラス11 ウェイト10-2)。
解説:ASINコード
ISBNの現行規格についても、識別番号が978であるものについては、桁数10-2は同一である。ただしチェックデジットの計算方法がモジュラス11 ウェイト10-2であるため、最後の1桁の数字が異なる。
モジュラス11 ウェイト10-2方式は、以下のように計算する。
- チェックデジットを除いた左側の桁から10,9,8‥‥2を掛けてそれらの和を取る。
- 和を11で割って出た余りを11から引く。
4×10+8×9+4×8+4×7+3×6+2×5+7×4+8×3+8×2=268となり、チェックデジットの 7 を得ることができる。
268%11=4
11-4=7
解説:ISBNとASINの関係
解説: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 = 10; pos >= 2; pos--) {
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 = 13; pos >= 2; pos--) {
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: }
ただ、入力値のチェックは細かく行っている。
入力値が10進数10桁なら旧ISBNとして処理をする。この際、チェックデジットが合っているかどうか検査する。※10桁の末尾が 'X' の時に正常に動作しませんでした。クロメルさん、ご指摘及び改良方法の提案をありがとうございました(2015年9月20日)。
入力値が10進数13桁なら現行ISBNとして処理をする。この際、チェックデジットがあっているかどうか検査する。また、上位3桁が978以外の場合は変換処理ができないようにしてある。
チェックデジットの計算には、ユーザー関数 cd10, cd11 を用意した。
参考サイト
- PHPでISBNコードをASINコードに変換する:ぱふぅ家のホームページ
- Quagga.js