先週末、QRコードを作るプログラムにとりかかることにした。
さて、、、
pdfはどこだ?
規格書をダウンロードした時にファイルを適当なフォルダに
放り込んでいたので、わからなくなってしまったのだ。
いや、そもそもどっちのパソコンで落としたんだっけ?
やばい。と焦ったのであったが、見つかった。よかった。
今度は、ファイルサーバーのしかるべき場所に保存しておかねば。
さて、、、
うむむ。。。
むぅ。
規格書は本文とたくさんの15の附属書からなっていた。
その間を行ったり来たりしつつ考え込むこと丸一日。
うん。よくわからないけど、まあいいや。
小さなことからこつこつと。
ひとつひとつ片付けよう。
大まかな手順で言うと
- 入力テキストの分析と符号化(0と1にする)
- 誤り訂正符号というものを生成する
- マトリックス(碁盤の目)に符号を並べる
- マスクなるものをかける
- 形式と型番を示す情報をつける
ということだ。
とりあえず、入力テキストの符号化を
やってみっぺ。
分析とは、、、
要するにQRコードにしたいテキストに含まれている
文字の種類を調べて、なるべくたくさんの文字を
詰め込めるように効率的に符号化しようということだ。
符号化とは、すべてを0と1で表そうということだ。
QRコードというのは、あの白と黒のつぶつぶが、
白は0、黒は1を意味しているのじゃ。
QRコードでは符号化のモードというものがあるが、
基本は、以下の4つのモードとその混在モードのようだ。
- 数字モード
- 英数字モード
- 8ビットバイトモード
- 漢字モード
規格によると、他に拡張チャネルモードとか構造的連接モードとか、
FNC1モードとかあるが、特定のアプリケーションに対応するものの
ようなので、今日のところは見逃してやろう。
で、ちいさなことからこつこつと。
数字モードは数字すなわち0〜9までの10種類の数字
だけを表現するモードだ。
話を進める前に、
さて、0から9までの10個を表すのに、最低必要な2進数の桁数
は何桁でしょう。
- 0 -> 0000
- 1 -> 0001
- 2 -> 0010
- 3 -> 0011
- 4 -> 0100
- 5 -> 0101
- 6 -> 0110
- 7 -> 0111
- 8 -> 1000
- 9 -> 1001
ということで4桁必要だということがわかる。
4桁で数字1文字を表現する方法だと、例えば
01234567という数字を符号化(1と0化)すると
0000 0001 0010 0011 0100 0101 0110 0111
となり全部で32桁となる。
しかしながら、本来4桁あれば、16種類の文字が
表現できる。さっきのに続けると、、、
- 10 -> 1010
- 11 -> 1011
- 12 -> 1100
- 13 -> 1101
- 14 -> 1110
- 15 -> 1111
というわけで使ってないパターンが6個ある。
よって、もったいないということになる。
さて、規格によるとQRコードの数字モードは
次のようにしている。
- まず3桁ずつにグループ分けする
012 345 67
- 各グループを10桁の2進数にする
※3桁の整数を表すのに2進数で10桁必要だからだ。
012 -> 0000001100
345 -> 0101011001
67 -> 1000011 ※元が2桁の場合は7桁、元が1桁の場合は4桁
- 2進データをつなぎ合わせる
0000001100 0101011001 1000011
この方法だと、上記の例では27桁で表現できている。
あと、符号化されたデータがどのように符号化されているのか
を示す情報が必要である。それをモード指示子という。
また、そのモードで何文字符号化されているか、文字数を示す必要が
ある。それを文字数指示子という。
- モード指示子は4桁で各モードで決められている。数字モードの場合は
0001
- 文字数指示子はQRコードの大きさ(これを型番という)によって
変わるが、小さいやつは10桁の2進数で表す。
上記の例だと、8文字だから
0000001000
これらを符号化されたデータの前に配置すると完成だ。
0001 0000001000 0000001100 0101011001 1000011
で、これをプログラムに書いてみた。
と、さらりと書いたが、実は結構苦労した。今回はVBで書いている。
VBでビット操作ってどうやるの?とか知らなかったので、
またググりまくった。ありがとう、Google とネットの人々よ。
VBはあまりこういうlow levelなことには向いてないのかも知れませんな。
その辺はまた別の機会にして、とにかく、プログラムはできた。
さてやってみよう。
0001 0000001000 0000001100 0101011001 1000011
OK、今日は完璧だ。
次回に続く
0 件のコメント:
コメントを投稿