◆PROCESSING 逆引きリファレンス
カテゴリー:文字関連処理
バーコードを読み書きするには
【概要】
日本で販売されている多くの商品には、商品を識別するためにバーコードが印刷されています。
バーコードには非常に多くの種類が存在します。
例えばコンビニやスーパーで売られている商品には、(必ずではありませんが)JAN13(EAN13)というタイプのバーコードがつけられています。
そんなバーコードをプログラムから読み書きできるライブラリが幾つか公開されています。
Javaから利用できる代表的なものには
があります。
今回はその中のZxingを使って、PROCESSINGでバーコードを読み書きする方法を紹介したいと思います。
なおPROCESSINGでQRコードを読み書きしたいのであれば、Zxingの便利なラッパーライブラリが、以下で公開されています。
私も enkatsu 様のライブラリを参考に、QRコードと幾つかの1次元バーコードを読み書きするライブラリを作成してみました。
利用したい方がいらっしゃいましたら、下記からダウンロード可能です。
本ライブラリはZxingをPROCESSINGから利用するためのラッパーライブラリです。本ライブラリのQR-CODEの読み書き処理は、Katsuya Endoh 様のオリジナルコード を元に作成されました。
本ライブラリは、参照元である Katuya Endoh 様に敬意を表し、オリジナルと同じ Apache License 2.0 で公開されています。
改良版のZxingP5のフォルダ構成は以下のようになっています。
フォルダ | 内容 |
---|---|
lib | PROCESSING用の Jarファイルと、Ver3.3.2のZxingライブラリが格納されています |
data | ZxingP5で作成したバーコードのサンプル画像が格納されています |
doc | ZxingP5のAPIドキュメントが格納されています |
src | ZxingP5のJavaソースファイルが格納されています |
ZXingで扱えるバーコード
Zxing(Ver 3.3.2)では、いくつかの1次元バーコドと2次元バーコードが読み書きできます。以下に一覧でまとめてみました。
(参照URL:株式会社エイポック 様)
これだけでも結構な数がありますが、世の中で利用されているバーコードは、まだまだあります(汗)。
GS1のバーコード画像は株式会社エイポック 様のホームページより拝借しました。そのほかのバーコードは、手元にあるZxingで出力しています。
色付きのバーコードが、改良版のZxingP5でサポートされているものです。
最新版のライブラリをダウンロードする
PROCESSING(Java)でZxingを利用するには、上記のGitHubからZxingの最新版(2018/05 現在 Ver3.3.2)をダウンロードして、ライブラリを作成します。
が・・・Javaのライブラリを自前で作成するのが面倒な場合は、Marven Repositoryからダウウンロード可能です。
ZXing Coreと ZXing Java SE Extensionsからcore-3.3.2.jar と javase-3.3.2.jarファイルを入手してください。
なおMSLABO作の 改良版のZxingP5を利用される場合は、本作業は必要ありません。
PROCESSINGで利用できるようにする
まずPROCESSINGの標準エディタから「新規プロジェクト」を作成し、空で良いので一度保存します。
なお保存前に「ファイル→設定」で、スケッチブックの場所に「わかりやすいパス」が指定されている事を確認してください。
上記例なら、スケッチを保存すると「D:\processing-3.3.6\src」に「sketch_180503a」などのフォルダが作成され、空のプログラムソースファイルができあがります。
このフォルダ(D:\processing-3.3.6\src\sketch_180503a)配下に、code フォルダを作成してください。
続いて、上記でダウンロードしたcore-3.3.2.jar と javase-3.3.2.jar を、code フォルダの中に複写します。
改良版のZxingP5を利用される場合は、ZxingP5を解凍してできた libフォルダの中身を複写してください。
※ZxingP5.jar は、改良版のZxingP5を利用する場合のみ必要となります。
Zxingのライブラリを利用される場合は、PROCESSINGのスケッチの先頭に以下の import 文を追記します。
import com.google.zxing.*;
また、改良版のZxingP5を利用される場合は
import ZxingP5.*;
を追記してください。
下記では、日常の商品で良く用いられているJAN13コードを読み書きする方法について説明します。なおJANコードは、国際的にはEANコードの仲間で、ZxingとZxingP5ではEANと呼称しています。
Zxingの詳細については、下記リファレンスを参照して下さい。また改良版のZxingP5を利用する場合は、doc フォルダ配下にある index.html を参照して下さい。
【詳細】
まずは本家Zxingを利用する方法です。
インスタンスを作成する(Zxing)
EAN13Writer writer13 = new EAN13Writer();
reader13 : EAN13読み取り用インスタンス
writer13 : EAN13書き込み用インスタンス
EANコードには、13桁のEAN13と8桁のEAN8があります。Zxingではどちらを読み書きしたいかに応じて、それぞれのクラスのインスタンスを作成する必要があります。
EAN13Reader/EAN13Writer はEAN13用のクラスです。EAN8Reader/EAN8Writer がEAN8用のクラスです。名前が異なるだけで使い方は同じですので、EAN8コードを読み書きしたい方は適時読み換えてください。
Writerは文字列をバーコード画像化するものです。Readerはその逆で、バーコードが含まれる画像から文字列を取得するものです。
EAN13を読み取る(Zxing)
result : 読み取り結果。ZxingのResult クラスのインスタンスで戻されます
bitmap : 読み取り画像。ZxingのBinaryBitmap クラスのインスタンスで与えます
hints : オプション指定。省略可能です
各クラスの詳細については、公式リファレンス を参照して下さい。
Resultクラスからは、読み取った文字列などが得られます。
なお decodeメソッドは、画像からバーコードが読み取れない場合はNotFoundException、バーコードの書式が不正な場合はFormatExceptionを発生させる事に注意してください。
文字列を得るString text = result.getText() ;
text :読み取った文字列
result : 読み取り結果。ZxingのResult クラスのインスタンス
読み取った文字列の最後の1文字はチェックデジットになります。
バーコードが含まれる画像は、ZxingのBinaryBitmap クラスのインスタンスで与えます。PROCESSINGの画像データ(PImage)を与える場合は、PImageをBinaryBitmap 形式に変換する必要があります。
手順としては、
- PImageをJavaのBufferedImageに変換
- BufferedImageをZxingのLuminanceSourceに変換
- LuminanceSourceをZxingのBinarizerに変換
- BinarizerをZxingのBinaryBitmapに変換
という4段階になります。面倒くさいですね・・・(汗)。
Binarizerを得る方法には、GlobalHistogramBinarizerを用いる方法とHybridBinarizerを用いる方法があります。
公式リファレンス によれば、CPUやメモリが少ないモバイルデバイスではGlobalHistogramBinarizerを、それ以外ではHybridBinarizerを用いる事が推奨されています。
この変換手順のサンプルが下記になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/** * BinaryBitmap化処理 * PImageをBinaryBitmapに変換する。 * * @param pImage 対象画像 * @return BinaryBitmap:成功<br>null:失敗 */ static BinaryBitmap changePImage2Bitmap(PImage pImage) { //PImageからBufferedImageを得る BufferedImage buf = (BufferedImage) pImage.getNative(); //BufferedImageをLuminanceSource化する LuminanceSource source = new BufferedImageLuminanceSource(buf); //LuminanceSourceからBinaryBitmapを作成する BinaryBitmap bitmap; bitmap = new BinaryBitmap(new GlobalHistogramBinarizer(source)); return bitmap; } |
理屈は小難しいですが、処理としてはそんなに長くはありませんよね(笑)。
hints には、読み取りオプションを指定可能です。hints 引数を省略する事も可能です。オプションについては公式リファレンス を参照してください。
例えば下記は、読み取り時にハードモード(精細モード)を指定する例です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
//解析モードを指定する(精度重視) Map<DecodeHintType,Object> hints = new HashMap<DecodeHintType, Object>(); hints.put( DecodeHintType.TRY_HARDER, true ); //バーコード解析 try { Result result = reader13.decode(bitmap, hints); } catch (NotFoundException e) { //例外発生 e.printStackTrace(); } catch (FormatException e) { //例外発生 e.printStackTrace(); } |
EAN13を作成する(Zxing)
EAN13を作成するBitMatrix bits = writer13 . encode(String src, BarcodeFormat format, int width, int height);
bits : 作成した画像データ。ZxingのBitMatrix クラスのインスタンス
src : 文字列
format : 作成フォーマット。EAN13なら BarcodeFormat.EAN_13 を指定
width : 作成する画像の幅
height : 作成する画像の高さ
与えた文字列から EAN13 のバーコード画像を作成します。
width と height には 0 以上の値を指定します。0または作成するバーコードの最小サイズより小さな値を指定した場合、Zxingが自動的に最適な(最小の)画像を作成します。
バーコード画像の作成に失敗すると、WriterException例外、またはIllegalArgumentException 例外が発生する事に注意してください。
例えばEAN13の場合、与える文字列は12文字か13文字の数字のみが許可されています。それ以外の長さの文字列を与えたり、数字以外の文字を与えるとIllegalArgumentExceptionになります。
また13文字の文字列を与える場合は、最後の1文字がチェックデジットとして正しい必要があります。チェックデジットとして不正な文字を与えるとIllegalArgumentExceptionになります。
チェックデジットとして正しい文字がわからない場合は、encodeメソッドに12文字を与えると、Zxingが自動的にチェックデジットを計算して付加してくれます。
画像の作成結果は、ZxingのBitMatrix クラスのインスタンスとして戻されます。
BitMatrix からPROCESSINGのPImageを得るには
- BitMatrixをJavaのBufferedImageに変換する
- BufferedImageをPROCESSINGのPImageに変換する
という手順を踏む必要があります。
BitMatrixをJavaのBufferedImageに変換するには、ZxingのMatrixToImageWriterクラスが持つtoBufferedImageメソッドを利用します。
この変換手順のサンプルが下記になります。
1 2 3 4 5 |
PImage changeBitMatrix2PImage(BitMatrix bitMatrix) { //変換する BufferedImage bImg = MatrixToImageWriter.toBufferedImage(bitMatrix); return new PImage( bImg ); } |
.
続いてZxingP5を利用する方法を紹介します。
インスタンスを作成する(ZxingP5)
EANWriter p5Writer = new EANWriter( PApplet this );
p5Reader : EAN読み取り用インスタンス
p5Writer : EAN書き込み用インスタンス
this : PAppletインスタンス。PROCESSINGでは this を与えます
ZxingP5では、EAN13とEAN8は共に EANWriter/EANReader クラスのインスタンスとして作成します。EANWriter/EANReader を使って、EAN13、EAN8の読み書きが可能です。
EAN13を読み取る(ZxingP5)
pImage: 読み取り画像。PImageをそのまま与えます。
globalHistogram: ヒストグラム(Binarizerを得る方法)指定
doRotate : 回転読み取り指定
text : 読み取った文字列
ZxingP5では、PImageをそのまま与えることが可能です。BinaryBitmap への変換はライブラリ側で行います。
読み取った文字列の最後の1文字はチェックデジットになります。
globalHistogramにはBinarizerを得る方法を指定します。
true ならGlobalHistogramBinarizerが、false なら HybridBinarizer を利用します。デフォルトは true です。
doRptate は省略可能な引数です。true を与えると、pImage を回転させながら解析します。デフォルトは false です。
回転解析は、バーコード画像が斜めに傾いている時などに威力を発揮します。
EAN13を作成する(ZxingP5)
EAN13を作成するPImage pImage = p5Writer . encode13(String src, int width, int height, boolean …appFont);
pImage : 作成した画像データ。成功ならPImage、失敗ならnullが戻されます
src : 文字列
width : 作成する画像の幅(0以上の値)
height : 作成する画像の高さ(0以上の値)
appFont : 文字列付加指示。true を指定すると画像化した文字列を付加します
与えた文字列から EAN13 のバーコード画像を作成します。画像はPImageで戻されます。
width と height には 0 以上の値を指定します。0または作成するバーコードの最小サイズより小さな値を指定した場合、ライブラリが自動的に最適な(最小の)画像を作成します。
ただし appFont に true を指定すると、高さに0を与えた場合でも、できあがる画像の高さは最小値にはなりません(文字を描画するぶんだけ、高さが増えます)。
EAN13の場合、与える文字列は12文字か13文字の数字のみが許可されています。それ以外の長さの文字列を与えたり、数字以外の文字を与えると画像作成に失敗します。
チェックデジットは、必ずライブラリ側で再計算されます。与えた文字列のチェックデジットが不正な場合は、正しいものに置き換わることに注意してください。
またZxingP5では文字列の先頭3文字を国コードとみなしてチェックします。国コードとして許可されていない文字列を与えると、画像の作成に失敗します。
日本の場合なら、先頭3文字は 450番台か490番台です。
なお国コードについては、以下のページを参考とさせていただきました。ありがとうございます。
ZxingP5はPROCESSINGから使いやすいように、面倒な処理をライブラリ側で行っていますので、生のZxingを使うのに比べて楽ができると思います(笑)。
【関連記事】
- なし
サンプルプログラム
ZxingでEAN13を読む例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
import com.google.zxing.*; import java.util.HashMap; import java.util.Map; import java.awt.image.BufferedImage; EAN13Reader Reader; PImage pImage; /** * PROCESSING Zxing EAN13 Read Sample * @auther MSLABO * @version 2018/05 1.0 */ void setup(){ size(300,300); //バーコード画像取得 pImage = loadImage("ean13Sample.png"); //インスタンス作成 Reader = new EAN13Reader(); //解析モードを指定する(精度重視) Map<DecodeHintType,Object> hints = new HashMap<DecodeHintType, Object>(); hints.put( DecodeHintType.TRY_HARDER, true ); //PImageをBinaryBitmapに変換する BinaryBitmap bitmap = changePImage2Bitmap(pImage); //バーコードを解析する Result result = null; try { result = Reader.decode(bitmap, hints); } catch (NotFoundException e) { //例外発生 e.printStackTrace(); } catch (FormatException e) { //例外発生 e.printStackTrace(); } //結果を得る if( result != null && result.getText() != null ){ println( result.getText() ); } } //PImageをBinaryBitmapに変換する BinaryBitmap changePImage2Bitmap(PImage pImage) { //PImageからBufferedImageを得る BufferedImage buf = (BufferedImage) pImage.getNative(); //BufferedImageをLuminanceSource化する LuminanceSource source = new BufferedImageLuminanceSource(buf); //LuminanceSourceからBinaryBitmapを作成する BinaryBitmap bitmap = null; bitmap = new BinaryBitmap(new GlobalHistogramBinarizer(source)); return bitmap; } void draw(){ background(255); image(pImage,0,0); } |
data フォルダにean13Sample.pngというEAN13が描かれたバーコード画像が格納されている前提です。
詳細で説明した命令を利用して、生のZxingでEAN13画像からコード内容を読み取ります。
ZxingでEAN13を作成する例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
import com.google.zxing.*; import java.awt.image.BufferedImage; EAN13Writer Writer; PImage pImage; /** * PROCESSING Zxing EAN13 Write Sample * @auther MSLABO * @version 2018/05 1.0 */ void setup(){ size(300,300); //インスタンス作成 Writer = new EAN13Writer(); //バーコード作成 BitMatrix bits = null; try{ //幅を最小にする。高さは60ピクセル bits = Writer.encode("012345678901", BarcodeFormat.EAN_13, 0, 60); } catch( WriterException e ){ //例外発生 e.printStackTrace(); } catch( IllegalArgumentException e){ //例外発生 e.printStackTrace(); } //結果をPImageに変換する if( bits != null ){ pImage = changeBitMatrix2PImage(bits); } } //BitMatrixをPImageに変換する PImage changeBitMatrix2PImage(BitMatrix bitMatrix) { //変換する BufferedImage bImg = MatrixToImageWriter.toBufferedImage(bitMatrix); return new PImage( bImg ); } void draw(){ background(255); if( pImage != null){ image(pImage,0,0); } } |
詳細で説明した命令を利用して、生のZxingで文字列からEAN13画像を作成します。
本例では文字列に12文字を与える事で、チェックデジットをZxingに計算させています。
ZxingP5でEAN13を読む例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
import ZxingP5.*; EANReader Reader; PImage pImage; /** * PROCESSING ZxingP5 EAN13 Read Sample * @auther MSLABO * @version 2018/05 1.0 */ void setup(){ size(300,300); //バーコード画像取得 pImage = loadImage("ean13Sample.png"); //インスタンス作成 Reader = new EANReader(this); //バーコードを解析する //globalHistogramにHybridBinarizerを指定 //画像を回転しながら読む String text = Reader.decode(pImage, false , true ); if( text != null ){ println( text ); } } void draw(){ background(255); image(pImage,0,0); } |
data フォルダにean13Sample.pngというEAN13が描かれたバーコード画像が格納されている前提です。
ZxingP5でEAN13バーコード画像を読み取ります。生のZxingを使うのに比べて、コードが短くなっているのがわかると思います。
ZxingP5でEAN13を作成する例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import ZxingP5.*; EANWriter Writer; PImage pImage; /** * PROCESSING ZxingP5 EAN13 Write Sample * @auther MSLABO * @version 2018/05 1.0 */ void setup(){ size(300,300); //インスタンス作成 Writer = new EANWriter(this); //バーコードを作成する //コード化した文字列を付加する pImage = Writer.encode13("4501234560123",0,60,true); } void draw(){ background(255); if( pImage != null ){ image(pImage,0,0); } } |
わざと間違えたチェックデジットを与えています。
画像化されたものは「4501234560125」で、元のチェックデジット(3)が正しい値(5)に訂正されている事に注意してください。
本ページで利用しているアイコン画像は、下記サイト様より拝借しております。各画像の著作権は、それぞれのサイト様および作者にあります。