ZXing(”Zebra Crossing”)を使用したQRコード生成ツールを作成しました。
ZXingはGoogleがオープンソースで公開しているQRコード生成ライブラリです。
Androidでも使用されていますが、今回はローカル起動までとなります。
以下では、Antを使用してビルドしていますので、Antのセットアップをしておいてください。
1. ZXing セットアップ
まず、Google CodeからZXingをダウンロードします。
任意のディレクトリへ展開します。私は “C:Eclipse_programzxing-1.6” としました。
次に展開済みのフォルダ内にある READ MEファイルを開き、ビルド用のコマンドを確認します。
Please refer to the project page for more information:
http://code.google.com/p/zxing/
in particular:
http://code.google.com/p/zxing/wiki/GettingStarted
To get started, you can try building and running the command-line client;
you will need to have Apache's Ant tool installed to run this:
ant -f core/build.xml
ant -f javase/build.xml
java -cp javase/javase.jar:core/core.jar com.google.zxing.client.j2se.CommandLineRunner [URL]
コマンドプロンプトを開き、展開をしたディレクトリへ移動し、12,13行目のAntコマンドを実行します。
C:Eclipse_programzxing-1.6>ant -f core/build.xml
Buildfile: C:Eclipse_programzxing-1.6corebuild.xml
clean:
[delete] Deleting directory C:Eclipse_programzxing-1.6corebuild
[delete] Deleting: C:Eclipse_programzxing-1.6corecore.jar
build:
init:
compile:
[mkdir] Created dir: C:Eclipse_programzxing-1.6corebuild
[javac] C:Eclipse_programzxing-1.6corebuild.xml:36: warning: 'includeant
runtime' was not set, defaulting to build.sysclasspath=last; set to false for re
peatable builds
[javac] Compiling 171 source files to C:Eclipse_programzxing-1.6corebuild
[jar] Building jar: C:Eclipse_programzxing-1.6corecore.jar
BUILD SUCCESSFUL
Total time: 10 seconds
C:Eclipse_programzxing-1.6>ant -f javase/build.xml
Buildfile: C:Eclipse_programzxing-1.6javasebuild.xml
init:
build:
[javac] C:Eclipse_programzxing-1.6javasebuild.xml:40: warning: 'includea
ntruntime' was not set, defaulting to build.sysclasspath=last; set to false for
repeatable builds
BUILD SUCCESSFUL
Total time: 0 seconds
最後にEclipseで使用する為に “C:Eclipse_programzxing-1.6corecore.jar” をライブラリ追加すればOKです。
2. 最終的なソースコード
何らかの文字列を入力すると、都度QRコードを生成するようになっています。
また、保存ボタン押下で生成済みのQRコードを保存します。
ちょっと怪しい部分もありますが、、ひとまず動くと思います。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Hashtable;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.google.zxing.qrcode.encoder.ByteMatrix;
import com.google.zxing.qrcode.encoder.Encoder;
import com.google.zxing.qrcode.encoder.QRCode;
public class Url2QR extends JFrame implements ActionListener {
private static Url2QR frame;
private final JTextField textField;
private final JButton dispButton;
private final JButton saveButton;
private final JLabel label;
private final JPanel panelTop;
private final JPanel panelBottom;
private final ImageIcon icon;
private final BufferedImage bufImg;
private static int SIZE = 4;
public Url2QR() throws WriterException {
super("QRコード生成");
panelTop = new JPanel();
panelBottom = new JPanel();
textField = new JTextField(20);
dispButton = new JButton("表示");
saveButton = new JButton("保存");
bufImg = barcodeWrite();
icon = new ImageIcon(bufImg);
label = new JLabel(icon);
Container container = getContentPane();
container.setLayout(new BorderLayout());
container.add(textField, BorderLayout.CENTER);
container.add(panelTop, BorderLayout.EAST);
container.add(panelBottom, BorderLayout.SOUTH);
panelTop.setLayout(new BorderLayout());
panelTop.add(dispButton, BorderLayout.WEST);
panelTop.add(saveButton, BorderLayout.EAST);
panelBottom.setLayout(new BorderLayout());
panelBottom.add(label, BorderLayout.WEST);
dispButton.setActionCommand("display");
dispButton.addActionListener(this);
saveButton.setActionCommand("save");
saveButton.addActionListener(this);
saveButton.setEnabled(false);
KeyListener keyListener = new KeyListener() {
public void keyPressed(KeyEvent keyEvent) {
}
public void keyReleased(KeyEvent keyEvent) {
repaintIcon();
}
public void keyTyped(KeyEvent keyEvent) {
}
};
textField.addKeyListener(keyListener);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("display")) {
repaintIcon();
} else if (e.getActionCommand().equals("save")) {
saveQR();
}
}
public void repaintIcon() {
try {
if (textField.getText().isEmpty()) {
saveButton.setEnabled(false);
} else {
saveButton.setEnabled(true);
}
label.setIcon(new ImageIcon(barcodeWrite()));
} catch (WriterException e) {
e.printStackTrace();
}
label.setToolTipText(textField.getText());
frame.pack();
}
public void saveQR() {
JFileChooser filechooser = new JFileChooser();
int selected = filechooser.showSaveDialog(this);
if (selected == JFileChooser.APPROVE_OPTION) {
File file = filechooser.getSelectedFile();
try {
ImageIO.write(barcodeWrite(), "png", file);
} catch (IOException e) {
System.out.println(e);
} catch (WriterException e) {
e.printStackTrace();
}
} else if (selected == JFileChooser.CANCEL_OPTION) {
} else if (selected == JFileChooser.ERROR_OPTION) {
label.setText("Error");
}
}
public BufferedImage barcodeWrite() throws WriterException {
Hashtable hints = new Hashtable();
hints.put(EncodeHintType.CHARACTER_SET, "SHIFT_JIS");
QRCode qrCode = new QRCode();
Encoder.encode(textField.getText(), ErrorCorrectionLevel.L, hints,
qrCode);
ByteMatrix byteMatrix = qrCode.getMatrix();
BufferedImage image = new BufferedImage(byteMatrix.getWidth() * SIZE,
byteMatrix.getHeight() * SIZE, BufferedImage.TYPE_4BYTE_ABGR);
if (!textField.getText().isEmpty()) {
Graphics2D g2D = image.createGraphics();
for (int y = 0; y < byteMatrix.getHeight(); y++) {
for (int x = 0; x < byteMatrix.getWidth(); x++) {
if (byteMatrix.get(x, y) == 1) {
g2D.setColor(Color.black);
} else {
g2D.setColor(Color.white);
}
g2D.fillRect(x * SIZE, y * SIZE, SIZE, SIZE);
}
}
}
return image;
}
public static void startGUI() throws WriterException {
frame = new Url2QR();
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
startGUI();
} catch (WriterException e) {
e.printStackTrace();
}
}
});
}
}