上野家のホームページ
ナーマル,マリン,ココ
[
新規
|
一覧
|
検索
|
最新
|
ヘルプ
]
開発/Barcode/QRコード/JavaでQRコードを作成
のソース
資料室
開発
/
Barcode
/
QRコード
/
JavaでQRコードを作成
のソース
[
差分
|
バックアップ
|
リロード
]
[ ]
差分
を表示
開発/Barcode/QRコード/JavaでQRコードを作成
へ行く。
* JavaでQRCodeを作成 [#i1074d87] ** 作成する方法 [#rec9e0a2] JavaでQRCodeを作成してみる。 QRコードを作成するためのJavaのライブラリに,ZXing(ゼブラ・クロッシング)というライブラリがある。~ ZXingはGoogleで開発されていて,様々な一次元/二次元のバーコードの生成/読み取りが出来るオープンソースライブラリ。Apache License 2.0で無償で利用出来ます。 サポートされているフォーマット形式は, |1D product |1D industrial |2D |h |UPC-A |Code 39 |QR Code | |UPC-E |Code 93 |Data Matrix | |EAN-8 |Code 128 |Aztec (beta) | |EAN-13 |Codabar |PDF 417 (beta)| | |ITF |MaxiCode | | |RSS-14 | | | |RSS-Expanded | | です。残念ながら,''MicroQRコードはサポートしていない''ようです。 このライブラリを使用して,QRコードを作成してみる。 ZXing Core(ZXingの中核となるライブラリ) groupId : com.google.zxing artifactId : core version : 3.3.2 ZXing Java SE Extensions(Java SEのプロジェクトで,バーコードを操作する場合のライブラリ) groupId : com.google.zxing artifactId : javase version : 3.3.2 Java SEで利用する場合はcoreとjavaseを,Androidの開発で利用する場合はcoreとandroidのコンポネントを利用する。 GitHub https://github.com/zxing/zxing からダウンロードする。~ もしくは,jarファイルをMaven Repositoryからだと取得しやすい。~ https://mvnrepository.com/artifact/com.google.zxing/core/3.3.2~ https://mvnrepository.com/artifact/com.google.zxing/javase/3.3.2~ ダウンロードした,以下の2つのjarファイルを使用する。 core-3.3.2.jar javase-3.3.2.jar 参照できるクラスパスにコピーしておく。 ソースコードからビルドする場合は,Mavenでビルドする。 $ cd work $ git clone https://github.com/zxing/zxing $ cd zxing $ mvn -Dhttps.protocols=TLSv1.2 package java 7の場合は,TSL 1.2を指定してビルドする。使用するのは,coreとjavaseに作成されたjarファイル。 ** QRCodeの画像をエンコードする [#l17e292a] QRCodeの画像を作成する方法は,以下のようなプログラムを作成。 ''QRCodeEncoder.java'' #code(java,nonumber){{ import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.WriterException; import com.google.zxing.client.j2se.MatrixToImageWriter; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.QRCodeWriter; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.concurrent.ConcurrentHashMap; import javax.imageio.ImageIO; /** * JavaでQR Codeを作成 * @author Yuji Ueno */ public class QRCodeEncoder { public static void main(String[] args) throws WriterException, IOException { // QRコード生成したい文字列 String source = "上野雄二"; // QRコード生成時のエンコーディング String encoding = "Shift_JIS"; // サイズ(ピクセル) int size = 100; // 画像ファイルの保存先 String filePath = "qrcode.png"; // 生成処理 ConcurrentHashMap hints = new ConcurrentHashMap(); //エラー訂正レベル指定 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); //エンコーディング指定 hints.put(EncodeHintType.CHARACTER_SET, encoding); //マージン指定 hints.put(EncodeHintType.MARGIN, 0); QRCodeWriter writer = new QRCodeWriter(); BitMatrix bitMatrix = writer.encode(source, BarcodeFormat.QR_CODE, size, size, hints); BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix); //ファイルへの保存処理 ImageIO.write(image, "png", new File(filePath)); } } }} コンパイルして,動作確認してみる。 $ javac -encoding UTF-8 QRCodeEncoder.java $ java QRCodeEncoder qrcode.pngのファイル名で画像が作成されている。 #ref(qrcode.png) 画像の色を変更したい場合には,MatrixToImageWriter.toBufferedImage()の第2引数に,MatrixToImageConfigを指定することで可能。 // 青と白で表示 MatrixToImageConfig config = new MatrixToImageConfig(0xff0000ff, 0xffffffff); BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(matrix, config); 画像ではなく,文字列でもよければBitMatrix.toString()が使える。 ** ヒント情報(EncodeHintType) [#hc73705d] QRCodeを作る際に,いくつかヒント情報を指定することが出来る。 ヒント情報は,Mapで指定する。~ キーは,列挙型のEncodeHintTypeを使用するが,キーによって値の型が異なるためMap<EncodeHintType, Object>で定義する。 また,キーが列挙型なのでEnumMapが使用出来る。 ** 誤り訂正レベル [#j7652ff7] 誤り訂正レベルは,以下のように指定する。~ キー : EncodeHintType.ERROR_CORRECTION 値 : 列挙型の ErrorCorrectionLevel で指定する ErrorCorrectionLevel.L : 7%まで訂正可能(デフォルト) ErrorCorrectionLevel.M : 15%まで訂正可能 ErrorCorrectionLevel.Q : 25%まで訂正可能 ErrorCorrectionLevel.H : 30%まで訂正可能 ちなみに,QRCodeにイラストなどを載せても読み取れるのは,この誤り訂正能力のおかげ。 ** 文字セット [#wb0d775a] 文字セットは,以下のように指定します。 キー : EncodeHintType.CHARACTER_SET 値 : 文字列( String )で文字セット名を指定 デフォルトは "ISO-8859-1" デフォルトは,上記のように"ISO-8859-1"(いわゆる ISO-Latin-1)なので,日本語が使えない。~ 必要であれば日本語が扱える文字セットを指定する必要がある。 後述のように,"Shift_JIS"の文字セット名は特別な対応があります(詳細は「モード」を参照)。 ** マージン [#we109dc3] マージンは,以下のように指定する。 キー : EncodeHintType.MARGIN 値 : 上下左右のマージンをセル数( Integer )で指定 デフォルトは 4 QRCodeには,周囲に4セル以上のマージンを必要とする。 普通は,デフォルトのままで十分だと思う。 もし,表示する際に画像の周りに余白を別途用意するなら,マージンには0を指定しても大丈夫。 ** モードやバージョンを取得する [#m2860f45] QRCodeには,「モード」や「バージョン」といった情報がありますが,基本的に自動的に判定される。 上記の方法では,実際に適用された「モード」や「バージョン」は取得出来ない。 もしなんらかの理由で,「モード」や「バージョン」が必要な場合(例えば,「バージョン」によって画像のサイズを 変えるなど)は,Encoderを使用する。 #code(java){{ package net.the_blue_pla.net.qrcode; import java.nio.charset.Charset; import java.util.EnumMap; import java.util.Map; import java.util.Objects; import com.google.zxing.EncodeHintType; import com.google.zxing.WriterException; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import com.google.zxing.qrcode.encoder.Encoder; import com.google.zxing.qrcode.encoder.QRCode; public class QRCodeUtils { public static QRCode createQRCode(String contents, ErrorCorrectionLevel level, Charset charset) throws WriterException { Objects.requireNonNull(contents); Objects.requireNonNull(level); Objects.requireNonNull(charset); if (!charset.canEncode()) { // エンコード不可 throw new IllegalArgumentException("cannot encode: " + charset.displayName()); } Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class); hints.put(EncodeHintType.CHARACTER_SET, charset.displayName()); QRCode code = Encoder.encode(contents, level, hints); return code; } } }} 注意:MatrixToImageWriter を使っていないので,「ZXing Java SE Extensions」は不要。 com.google.zxing.qrcode.encoder.QRCode QRCodeは,以下の情報を持っている。 QRCode#getVersion() - バージョン QRCode#getECLevel() - 誤り訂正レベル QRCode#getMode() - モード QRCode#getMatrix() - QRコードの白黒情報 QRCodeから画像データを直接作るメソッドなどは用意されていないが,QRCode.getMatrix() から必要な情報は取得可能。 QRCodeから独自に画像を作るなら,QRCodeWriterとMatrixToImageWriterが参考になる。(面倒なら,かつ性能的に問題なければ QRCodeWriter を使えばいいのだが) ** バージョン [#w2e91795] バージョンとは,QRCodeのセル数の大きさを表す。~ 一番小さい「バージョン1」は,21セルx21セル。~ バージョンが1つ増える毎に,縦横ともに4セルずつ増えていく。~ 最大の「バージョン40」は,177セルx177セルになる。~ |バージョン |縦横のセル数 |h |バージョン1 |21セル×21セル | |バージョン2 |25セル×25セル | |… |… | |バージョンn |(17+4*n)セル×(17+4*n)セル| |… |… | |バージョン40|177セル×177セル | ** モード [#ob7ca99e] QRCodeモード( com.google.zxing.qrcode.decoder.Mode )には,以下のものがある。 |モード |許容される文字|h |数字(NUMERIC) |数字のみ (0~9)| |英数字(ALPHANUMERIC) |数字,英大文字と一部の記号 (0~9, A~Z, スペース, '$', '%', '*', '+', '-', '.', '/', ':')| |漢字(KANJI) |Shift_JISの2バイトコードのみ| |バイト(BYTE) |8bitのデータすべて| 他にも「混在モード」があるが,どうもZXing 3.3.2ではサポートされていないみたい。~ モードについては,ちょっと変わった判定方法になっている。 指定した文字セットが,"Shift_JIS"かそうでないかで判定方法が異なる。 *** 文字セットが,"Shift_JIS"以外の場合の判定 [#m9d621ec] 文字セットが"Shift_JIS"でない場合には,以下のようになっている。 対象のデータが数字のみの場合 ⇒ 数字モード 対象のデータが英数字と一部の記号のみの場合 ⇒ 英数字モード それ以外のデータが含まれる ⇒ バイトモード 英数字モードでの英字は英大文字のみ。 英小文字があるとバイトモードになってしまう。 *** 文字セットが"Shift_JIS"の場合の判定 [#n922eac0] 文字セットが"Shift_JIS"の場合には,以下のようになっている。 対象のデータが"Shift_JIS"の2バイト文字のみの場合 ⇒ 漢字モード それ以外のデータが含まれる ⇒ バイトモード つまり,文字セットとして"Shift_JIS"を指定した場合には,対象データが数字だけであってもバイトモードになるようだ。 また,この判定は"Shift_JIS"を指定した場合のみの動作になっている。 例えば,別名の"SJIS"や,"shift_jis"のように小文字で指定した場合は,上記「文字コードが"Shift_JIS"以外の場合の判定」が使われる。 当然だが,"MS932" や "Windows-31J" についても,上記「文字コードが"Shift_JIS"以外の場合の判定」が使われる。 そのため漢字モードでは,「NEC特殊文字」「NEC選定IBM拡張文字」「IBM拡張文字」「ユーザ外字」などは使えない。 ちなみに,このあたりの判定は com.google.zxing.qrcode.encoder.Encoder で行っています。 ''Encoder.java'' #code(java,nonumber){{ // (略) private static Mode chooseMode(String content, String encoding) { if ("Shift_JIS".equals(encoding)) { // Choose Kanji mode if all input are double-byte characters return isOnlyDoubleByteKanji(content) ? Mode.KANJI : Mode.BYTE; } // (略) }} つまり,文字セットとして"Shift_JIS"を指定した場合には,対象データが数字だけであってもバイトモードになるようだ。~ うーむ,この動作はおかしい気がする・・・~ 3.3.2では,"Shift_JIS"でもNUMERIC/ALPHANUMERICに判定されるように修正されているっぽい。 * QRCodeの画像を読み取る [#lb703bf2] ZXingは,読み取りにも対応している。 QRCodeの画像を読み取るために,以下のようなプログラムを作成。~ ''QRCodeReader.java'' #code(java,nonumber){{ import com.google.zxing.BinaryBitmap; import com.google.zxing.ChecksumException; import com.google.zxing.FormatException; import com.google.zxing.LuminanceSource; import com.google.zxing.MultiFormatReader; import com.google.zxing.NotFoundException; import com.google.zxing.Reader; import com.google.zxing.Result; import com.google.zxing.client.j2se.BufferedImageLuminanceSource; import com.google.zxing.common.HybridBinarizer; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; /** * * @author Yuji Ueno */ public class QRCodeReader { public static void main(String[] args) throws IOException, NotFoundException, ChecksumException, FormatException { //読み取りたい画像ファイルの保存場所 String filePath = "qr_code.png"; //読み取り処理 BufferedImage image = ImageIO.read(new File(filePath)); LuminanceSource source = new BufferedImageLuminanceSource(image); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); Reader reader = new MultiFormatReader(); Result decodeResult = reader.decode(bitmap); //デコード処理 String result = decodeResult.getText(); //標準出力 System.out.format("読み取り結果=%1$s\r\n", result); } } }} コンパイルして,動作確認してみる。 > javac -encoding UTF-8 QRCodeReader.java > java QRCodeReader 読み取り結果=上野雄二 となって,作成したときの文字列が読めた。
開発/Barcode/QRコード/JavaでQRコードを作成 のバックアップソース(No. All)
現: 2024-04-09 (火) 14:49:53
yuji
Counter: 150, today: 2, yesterday: 0
Copyright©2008 Yuji Ueno All Rights Reserved.
ログイン
ユーザ名:
パスワード:
IDとパスワードを記憶
パスワード紛失
メインメニュー
ホーム
でぶlog
資料室
最新ページ一覧
全ページ一覧
ヘルプ
» 関連ページ
» Wikiソース
» 編集履歴
» バックアップ一覧
» 添付ファイル一覧
フォーラム
お問い合わせ