Java

ZXingを使ってPDF417バーコードの生成/読み取りを行う

前回の記事では、ZXingを使ってQRコードを生成する方法を解説しました。

ZXingを使ってQRコードの生成/読み取りを行うURLやSNSのIDなど、さまざな情報を共有できる手段として QRコード は浸透してきました。人間にはそのQRコードに格納された情報を理...

本稿では、二次元コードを生成できる Java のライブラリ ZXing を使って、PDF417 バーコードを生成/読み取りする方法について解説します。

こんな人におすすめ
  • EDIデータの管理・運営にバーコードの読み書きが必要である
  • QRコード以外の二次元コードに興味があり、自分で生成したい

PDF417とは

PDF417はスタック型の二次元コードです。縦横のデザインが容易に変更できること、優れたエラー訂正機能を持っていることなどから、多方面から高く評価・採用されました。とくに、国際標準物流ラベル(ISO 15394/JIS X 0515)において、EDIデータの標準シンボルとして採用されています。

セットアップ

ZXingはGithubのページ https://github.com/zxing/zxing ではjarが配布されていません。Mavenのリポジトリよりダウンロードできるので、core-*.*.*.jar と javase-*.*.*.jar をダウンロードしてクラスパスに追加してください。

https://repo1.maven.org/maven2/com/google/zxing/core/3.4.0/core-3.4.0.jar

https://repo1.maven.org/maven2/com/google/zxing/javase/3.4.0/javase-3.4.0.jar

Mavenを使用する場合は、pom.xmlに以下の定義を追加してください。

pom.xml

<!-- https://mvnrepository.com/artifact/com.google.zxing/core -->
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.4.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.google.zxing/javase -->
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.4.0</version>
</dependency>

サンプルソース

基本

生成処理

以下のソースはPDF417Writerを使って、URL「http://develman.net」をQRコードにエンコードして、「pdf417.png」という画像ファイルに出力するサンプルです。以降の生成処理の解説のベースとしています。

Java

package net.develman.barcode;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.pdf417.PDF417Writer;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class ZxingPDF417WriterExample {

    public static final void main(String[] args) {
        String content = "https://develman.net";
        int width = 300;
        int height = 124;
        String output = "pdf417_1.png";

        try {
            PDF417Writer writer = new PDF417Writer();

            //PDF417Writer#encode()には以下の情報を渡す
            // (1)エンコード対象の文字列、バーコードに埋め込みたい情報
            // (2)出力するバーコードの書式
            // (3)イメージの幅
            // (4)イメージの高さ
            BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.PDF_417, width, height);

            BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix);

            //エンコードで得られたイメージを画像ファイルに出力する
            ImageIO.write(image, "png", new File(output));

        } catch (WriterException e) {
            System.err.println("[" + content + "] をエンコードするときに例外が発生.");
            e.printStackTrace();
        } catch (IOException e) {
            System.err.println("[" + output + "] を出力するときに例外が発生.");
            e.printStackTrace();
        }
    }
}

上のコードを実行すると画像ファイルとして得ることができます。

読み取り処理

以下のソースはPDF417Readerを使って、「pdf417.png」という画像ファイルをデコードしてURL「http://develman.net」を読み取るサンプルです。

Java

package net.develman.barcode;

import com.google.zxing.*;
import com.google.zxing.aztec.AztecReader;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.pdf417.PDF417Reader;
import com.google.zxing.pdf417.PDF417Writer;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class ZxingPDF417ReaderExample {

    public static final void main(String[] args) {
        String input = "pdf417.png";

        try {
            //画像データを読み込む
            BufferedImage image = ImageIO.read(new File(input));
            LuminanceSource source = new BufferedImageLuminanceSource(image);
            Binarizer binarizer = new HybridBinarizer(source);
            BinaryBitmap bitmap = new BinaryBitmap(binarizer);

            PDF417Reader reader = new PDF417Reader();

            //PDF417Reader#decode()には以下の情報を渡す
            // (1)読み込んだイメージ
            Result result = reader.decode(bitmap);

            System.out.println(result.getText());

        } catch (NotFoundException e) {
            System.err.println("[" + input + "] イメージの中にバーコードが見つからないためデコードで例外が発生.");
            e.printStackTrace();
        } catch (ChecksumException e) {
            System.err.println("[" + input + "] バーコードが見つかったがチェックサム検査で例外が発生.");
            e.printStackTrace();
        } catch (FormatException e) {
            System.err.println("[" + input + "] は書式不正のためデコードで例外が発生.");
            e.printStackTrace();
        } catch (IOException e) {
            System.err.println("[" + input + "] を読み込むときに例外が発生.");
            e.printStackTrace();
        }
    }
}

実行結果

https://develman.net

コンパクトモードを指定する

encode時にエンコードヒントを指定することで、コンパクトPDF417を生成できます。

印字領域確保が最も重要で、シンボル自体の損傷が極めて考えにくい場合は、右行指示子を省略し、ストップパターンを1モジュール幅のバーに縮小したシンボルを使用することができます。右行指示子の省略とストップパターンを縮小化したPDF417を、コンパクトPDF417といいます。

生成処理

Java

String content = "https://develman.net";

Hashtable hints = new Hashtable();
hints.put(EncodeHintType.PDF417_COMPACT, true);

PDF417Writer writer = new PDF417Writer();
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.PDF_417, 300, 124, hints);
BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix);
ImageIO.write(image, "png", new File("pdf417_1.png"));
PDF417 コンパクトON縮小化されたシンボルの例
PDF417 コンパクトOFF縮小化されていないシンボルの例

行数・列数を指定する

encode時にエンコードヒントを指定します。
PDF417のコードサイズは横方向1~30コードワード、縦方向3~90段です。EncodeHintType.PDF417_DIMENSIONSを指定すれば、行数は1〜30行、列数は3〜90列の範囲で指定サイズのシンボルを生成できます。

生成処理

Java

String content = "https://develman.net";

Hashtable hints = new Hashtable();
hints.put(EncodeHintType.PDF417_DIMENSIONS, new Dimensions(30,30,3,90));

PDF417Writer writer = new PDF417Writer();
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.PDF_417, 300, 124, hints);
BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix);
ImageIO.write(image, "png", new File("pdf417_3.png"));
PDF417 行数30指定の例minCol=30, maxCol=30 を指定した例
PDF417 列数90指定の例minRow=90, maxRow=90 を指定した例

圧縮モードを指定する

encode時にエンコードヒントを指定します。
EncodeHintType.PDF417_COMPACTIONに指定できるのは4種類です。

  • Compaction.AUTO
  • Compaction.BYTE
  • Compaction.NUMERIC
  • Compaction.TEXT

圧縮モード時の情報密度は、数字のみの場合は約3文字/コードワード、英数字の場合は約2文字/コードワード、漢字を含む2バイト文字は約0.5文字/コードワードです。

生成処理

Java

String content = "https://develman.net";

Hashtable hints = new Hashtable();
//指定できる圧縮モードは4種類
//Compaction.AUTO
//Compaction.BYTE
//Compaction.NUMERIC
//Compaction.TEXT
hints.put(EncodeHintType.PDF417_COMPACTION, Compaction.TEXT);

PDF417Writer writer = new PDF417Writer();
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.PDF_417, 300, 124, hints);
BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix);
ImageIO.write(image, "png", new File("pdf417_5.png"));
ABOUT ME
sasakiyu
ひ弱で優しい少年だったが、デーモンと合体。 強大な力を得つつも人間の心を失わないデベルマンとなる。