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();
}
}
}