金曜日, 8月 05, 2011

QRコードを作るプログラムを作る(1)

JISの規格書を購入してから半月ほどたって、
先週末、QRコードを作るプログラムにとりかかることにした。

さて、、、

pdfはどこだ?

規格書をダウンロードした時にファイルを適当なフォルダに
放り込んでいたので、わからなくなってしまったのだ。
いや、そもそもどっちのパソコンで落としたんだっけ?
やばい。と焦ったのであったが、見つかった。よかった。
今度は、ファイルサーバーのしかるべき場所に保存しておかねば。

さて、、、
うむむ。。。
むぅ。
規格書は本文とたくさんの15の附属書からなっていた。
その間を行ったり来たりしつつ考え込むこと丸一日。

うん。よくわからないけど、まあいいや。
小さなことからこつこつと。
ひとつひとつ片付けよう。

大まかな手順で言うと
  1. 入力テキストの分析と符号化(0と1にする)
  2. 誤り訂正符号というものを生成する
  3. マトリックス(碁盤の目)に符号を並べる
  4. マスクなるものをかける
  5. 形式と型番を示す情報をつける
ということだ。
とりあえず、入力テキストの符号化を
やってみっぺ。

分析とは、、、
要するに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コードの数字モードは
次のようにしている。
  1. まず3桁ずつにグループ分けする
         012 345 67
  2. 各グループを10桁の2進数にする
    ※3桁の整数を表すのに2進数で10桁必要だからだ。
    012 -> 0000001100
    345 -> 0101011001
    67   -> 1000011     ※元が2桁の場合は7桁、元が1桁の場合は4桁
  3. 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 件のコメント: