JavaでQRコードを作る・読む「ZXing」
    バーコードやQRコードの二次元コードのエンコード・デコード処理を実装した「ZXing(ゼブラ・クロッシング)」というオープンソースのJavaのライブラリを使った、簡単なQRコードの作成と読み取りを行うJavaサンプルを紹介します。
    ZXingは次のGitHubから入手できます。
    ここからコンパイルしなくても、jarファイルがMavenのリポジトリから提供されています。core-x.x.x.jarと、javase-x.x.x.jarをダウンロードしてください(この時点では3.5.0が最新でした)。
    簡単なQRコードの作成(エンコード)
    QRコードを生成する最も簡単な例です。QRCoreWriteクラスのencodeメソッドによりQRコードを生成し、png画像に出力します。
    zxtest_enc1.java
    import java.io.*;
    import java.awt.image.BufferedImage;
    import javax.imageio.ImageIO;
    
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.client.j2se.MatrixToImageWriter;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.qrcode.QRCodeWriter;
    
    public class zxtest_enc1 {
    
        public static void main(String[] args) {
            try {
                QRCodeWriter qw = new QRCodeWriter();
                BitMatrix bm = qw.encode("ZXing QR code", BarcodeFormat.QR_CODE, 200, 200);
                BufferedImage img = MatrixToImageWriter.toBufferedImage(bm);
                ImageIO.write(img, "png", new File("zxtest.png"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    次のようにコンパイルし、実行します。
    javac -classpath core-3.5.0.jar:javase-3.5.0.jar zxtest.java
    java -classpath core-3.5.0.jar:javase-3.5.0.jar: zxtest 
    -classpathは「:」で区切って複数指定できます。Windowsの場合は「;」で区切ります。
    文字列「ZXing QR code」を記録したQRコード画像「zxtest01.png」が出力されます。画像をスマートフォンなどで読み取ると、「ZXing QR code」が記録されていることが確認できるはずです。
 
    encodeメソッドの引数は次の通りです。
    
        
            | String contents | QRコードの文字列データ | 
        
            | BarcodeFormat format | BarcodeFormat.QR_CODE(QRコードを指定) ZXingはバーコードもサポートしている
 | 
        
            | int width, height | 画像サイズ(ピクセル) 通常は正方形で指定する
 | 
    
 
    この例では、バージョンや誤り訂正レベルを指定していません。その場合は、最適なバージョンが自動的に割り当てられ、誤り訂正は最低レベル「L」が適用されます。
    上の例の画像データのファイル出力部分は、j2seパッケージのMatrixToImageWriterクラスを使えば更に簡単に実装できます。出力結果は上と同じです。
    zxtest_enc2.java
    import java.io.*;
    
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.client.j2se.MatrixToImageWriter;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.qrcode.QRCodeWriter;
    
    public class zxtest_enc2 {
    
        public static void main(String[] args) {
            try {
                QRCodeWriter qw = new QRCodeWriter();
                BitMatrix bm = qw.encode("ZXing QR code", BarcodeFormat.QR_CODE, 200, 200);
                MatrixToImageWriter.writeToFile(bm, "png", new File("zxtest.png"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    デコード
    次は、QRコードを含む画像ファイル(zxtest.png)を読み取り、内容を文字列とバイトデータで表示します。QRCodeReaderクラスのdecodeメソッドによりQRコードをデコードします。
    zxtest_dec1.java
    import java.awt.image.BufferedImage;
    import java.io.File;
    
    import javax.imageio.ImageIO;
    
    import com.google.zxing.Binarizer;
    import com.google.zxing.BinaryBitmap;
    import com.google.zxing.LuminanceSource;
    import com.google.zxing.Result;
    import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
    import com.google.zxing.common.HybridBinarizer;
    import com.google.zxing.qrcode.QRCodeReader;
    
    public class zxtest_dec1 {
    
        public static void main(String[] args) {
            try {
                BufferedImage img = ImageIO.read(new File("zxtest.png"));
                LuminanceSource src = new BufferedImageLuminanceSource(img);
                Binarizer bin = new HybridBinarizer(src);
                BinaryBitmap bm = new BinaryBitmap(bin);
    
                QRCodeReader qrr = new QRCodeReader();
                Result result = qrr.decode(bm);
                String tdata = result.getText();
                System.out.println(tdata);
                byte[] bdata = tdata.getBytes();
                for (byte d: bdata)
                    System.out.printf("%02x ", d);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    次のように読み取ったデータの内容が表示されます。
    ZXing QR code
    5a 58 69 6e 67 20 51 52 20 63 6f 64 65
    誤り訂正・バージョンを指定してエンコード
    encodeメソッドには、Mapでエンコードのオプションを追加して与えることができます。最初の例のencodeメソッドの末尾にMapを設定するもう一つのencodeメソッドを使います。
    zxtest_enc3.java
    import java.io.*;
    import java.util.*;
    
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.client.j2se.MatrixToImageWriter;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.qrcode.QRCodeWriter;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    
    public class zxtest_enc3 {
    
        public static void main(String[] args) {
            try {
                Map<EncodeHintType, Object> hints = new HashMap<>();
                hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);     // L, M, Q, H 
                hints.put(EncodeHintType.MARGIN, 2);                                    // マージンのセル数
                hints.put(EncodeHintType.QR_VERSION, 3);                                // バージョン
    
                QRCodeWriter qw = new QRCodeWriter();
                BitMatrix bm = qw.encode("ZXing QR code", BarcodeFormat.QR_CODE, 200, 200, hints);
                MatrixToImageWriter.writeToFile(bm, "png", new File("zxtest.png"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
 
    マップのキーにenum EncodeHintTypeの種別を指定し、それぞれ設定します。
    
        
            | EncodeHintType.ERROR_CORRECTION | 誤り訂正レベル | ErrorCorrectionLevel.L ErrorCorrectionLevel.M
 ErrorCorrectionLevel.Q
 ErrorCorrectionLevel.H
 | 
        
            | EncodeHintType.MARGIN | 外側のマージン(余白)のセル数 | 1〜 | 
        
            | EncodeHintType.QR_VERSION | バージョン | 1〜40 | 
        
            | EncodeHintType.CHARACTER_SET | 文字コード名 | "Shift_JIS" StandardCharsets.UTF_8
 | 
    
    日本語を含むエンコード
    データに日本語を含む場合は、hintsに文字コードセットを指定します。QRコードの規則で日本語はシフトJISとされています。
    zxtest_enc4.java
    import java.io.*;
    import java.util.*;
    
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.client.j2se.MatrixToImageWriter;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.qrcode.QRCodeWriter;
    import com.google.zxing.EncodeHintType;
    
    public class zxtest_enc4 {
    
        public static void main(String[] args) {
            try {
                Map<EncodeHintType, Object> hints = new HashMap<>();
                hints.put(EncodeHintType.CHARACTER_SET, "Shift_JIS");
                QRCodeWriter qw = new QRCodeWriter();
                BitMatrix bm = qw.encode("日本語ABC012", BarcodeFormat.QR_CODE, 200, 200, hints);
                MatrixToImageWriter.writeToFile(bm, "png", new File("zxtest.png"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
 
    バイナリデータのエンコード
    QRCodeWriterクラスのencodeメソッドへ与えるデータはString型ですが、バイト型配列をStringに変換することでバイナリデータが格納ができます。
    zxtest.java
    import java.io.*;
    import java.util.*;
    
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.client.j2se.MatrixToImageWriter;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.qrcode.QRCodeWriter;
    
    public class zxtest {
    
        public static void main(String[] args) {
            try {
                QRCodeWriter qw = new QRCodeWriter();
                byte[] data = {0x01, 0x02, 0x00, 0x04, 0x05}; 
                BitMatrix bm = qw.encode(new String(data), BarcodeFormat.QR_CODE, 200, 200);
                MatrixToImageWriter.writeToFile(bm, "png", new File("zxtest.png"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
