使用zxing编写的二维码生成解析工具:QRCoder

zxing GitHub地址

QRCoder GitHub地址

TipDialog.java

package com.wolf_pan;

import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class TipDialog extends JDialog {

    public TipDialog(JFrame owner, String tip, int width, int height) {
        super.setUndecorated(true);
        super.setSize(width, height);
        super.setLocationRelativeTo(owner);
        super.add(new JLabel("<html><font color="red">" + tip + "</font></html>", JLabel.CENTER));
    }

    public void show(long duration) {
        setVisible(true);
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                dispose();
            }
        }, duration);
    }
}

PicFileChooser.java

package com.wolf_pan;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;

public class PicFileChooser extends JFileChooser {

    public PicFileChooser() {

        FileNameExtensionFilter filter1 = new FileNameExtensionFilter("ICO (*.ico)", "ico");
        FileNameExtensionFilter filter2 = new FileNameExtensionFilter("PNG (*.png)", "png");
        FileNameExtensionFilter filter3 = new FileNameExtensionFilter("TIFF (*.tif;*.tiff)", "tif", "tiff");
        FileNameExtensionFilter filter4 = new FileNameExtensionFilter("GIF (*.gif)", "gif");
        FileNameExtensionFilter filter5 = new FileNameExtensionFilter("JPEG (*.jpg;*.jpeg;*.jpe;*.jfif)", "jpg", "jpeg", "jpe", "jfif");
        FileNameExtensionFilter filter6 = new FileNameExtensionFilter("Bitmap Files (*.bmp)", "bmp", "dib");
        FileNameExtensionFilter filter7 = new FileNameExtensionFilter("All Picture Files", "ico", "png", "tif", "tiff", "gif", "jpg", "jpeg", "jpe", "jfif", "bmp", "dib");
        super.setFileFilter(filter1);
        super.setFileFilter(filter2);
        super.setFileFilter(filter3);
        super.setFileFilter(filter4);
        super.setFileFilter(filter5);
        super.setFileFilter(filter6);
        super.setFileFilter(filter7);
        super.setAcceptAllFileFilterUsed(false);
    }
}

MainFrame.java

package com.wolf_pan;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.EncodeHintType;
import com.google.zxing.FormatException;
import com.google.zxing.NotFoundException;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import com.google.zxing.qrcode.QRCodeWriter;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
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.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.event.ChangeEvent;
import javax.swing.filechooser.FileNameExtensionFilter;

public class MainFrame extends JFrame {

    private JTabbedPane tabbedPane;
    private HintTextArea textToEncodeHintTextArea;
    private JTextArea decodedResultTextArea;
    private JLabel encodedImageLabel, qrcodeToDecodeLabel, tipLabel;
    private JButton encodeButton, chooseButton, decodeButton, contactAuthorButton;
    private JPopupMenu popupMenu;
    private JMenuItem copyMenuItem, saveMenuItem;
    private BufferedImage qrcodeBufferedImage;
    private String qrcodePicFilename;
    private static final Logger LOGGER = Logger.getLogger(MainFrame.class.getName());

    private MainFrame() {
        super("QRCoder");
        initializeComponents();
        initializeEventListeners();
    }

    private void initializeComponents() {
        setSize(400, 600);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        tabbedPane = new JTabbedPane();
        JPanel encodePanel = new JPanel(new BorderLayout()), decodePanel = new JPanel(new BorderLayout()), authorPanel = new JPanel(new BorderLayout());
        textToEncodeHintTextArea = new HintTextArea("Type text you want to encode here", 4);
        encodePanel.add(new JScrollPane(textToEncodeHintTextArea), BorderLayout.NORTH);
        encodedImageLabel = new JLabel();
        encodedImageLabel.setHorizontalAlignment(JLabel.CENTER);
        encodePanel.add(encodedImageLabel);
        JPanel southEncodePanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 0));
        tipLabel = new JLabel("<html><font color="blue" size="8">Tip</font></html>");
        southEncodePanel.add(tipLabel);
        encodeButton = new JButton("Encode");
        southEncodePanel.add(encodeButton);
        encodePanel.add(southEncodePanel, BorderLayout.SOUTH);
        tabbedPane.add("Encode", encodePanel);
        JPanel northPanel = new JPanel(new BorderLayout());
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        chooseButton = new JButton("Choose...");
        buttonPanel.add(chooseButton);
        decodeButton = new JButton("Decode");
        buttonPanel.add(decodeButton);
        northPanel.add(buttonPanel, BorderLayout.NORTH);
        decodedResultTextArea = new JTextArea(4, 0);
        decodedResultTextArea.setLineWrap(true);
        decodedResultTextArea.setEditable(false);
        JPanel decodedResultPanel = new JPanel(new BorderLayout());
        JLabel decodedResultLabel = new JLabel("<html><font size="5">Decoded result:</font></html>");
        decodedResultPanel.add(decodedResultLabel, BorderLayout.NORTH);
        decodedResultPanel.add(new JScrollPane(decodedResultTextArea));
        northPanel.add(decodedResultPanel);
        decodePanel.add(northPanel, BorderLayout.NORTH);
        qrcodeToDecodeLabel = new JLabel(new ImageIcon(MainFrame.class.getResource("/images/author.jpg")));
        decodePanel.add(qrcodeToDecodeLabel);
        tabbedPane.add("Decode", decodePanel);
        JLabel authorLabel = new JLabel("<html><br /><font size="20">作者:布伊什<br />QQ: 980639902</font></html>", JLabel.CENTER);
        authorPanel.add(authorLabel, BorderLayout.NORTH);
        JLabel authorQRCodeLabel = new JLabel(new ImageIcon(MainFrame.class.getResource("/images/author.jpg")));
        authorPanel.add(authorQRCodeLabel);
        contactAuthorButton = new JButton("联系作者");
        JPanel contactAuthorButtonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        contactAuthorButtonPanel.add(contactAuthorButton);
        authorPanel.add(contactAuthorButtonPanel, BorderLayout.SOUTH);
        tabbedPane.add("Author", authorPanel);
        add(tabbedPane);
        popupMenu = new JPopupMenu();
        copyMenuItem = new JMenuItem("Copy");
        popupMenu.add(copyMenuItem);
        saveMenuItem = new JMenuItem("Save");
        popupMenu.add(saveMenuItem);
    }

    private void initializeEventListeners() {
        tabbedPane.addChangeListener((ChangeEvent ev) -> {
            if (tabbedPane.getSelectedIndex() == 0) {
                encodeButton.requestFocus();
            }
        });
        encodeButton.addActionListener((ActionEvent ev) -> {
            onEncodeButtonClicked();
        });
        chooseButton.addActionListener((ActionEvent ev) -> {
            onChooseButtonClicked();
        });
        decodeButton.addActionListener((ActionEvent ev) -> {
            onDecodeButtonClicked();
        });
        contactAuthorButton.addActionListener((ActionEvent ev) -> {
            onContactAuthorButtonClicked();
        });
        encodedImageLabel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent ev) {
                onEncodedImageLabelClicked(ev);
            }
        });
        tipLabel.addMouseListener(new MouseAdapter() {
            private TipDialog tipDialog;

            @Override
            public void mouseEntered(MouseEvent ev) {
                tipDialog = new TipDialog(MainFrame.this, "右键单击生成的二维码弹出工具菜单", 220, 30);
                tipDialog.setVisible(true);
            }

            @Override
            public void mouseExited(MouseEvent ev) {
                tipDialog.dispose();
            }
        });
        copyMenuItem.addActionListener((ActionEvent ev) -> {
            onCopyMenuItemClicked();
        });
        saveMenuItem.addActionListener((ActionEvent ev) -> {
            onSaveMenuItemClicked();
        });
    }

    private void onEncodeButtonClicked() {
        try {
            String contents = textToEncodeHintTextArea.getText();
            int width = encodedImageLabel.getWidth() - 20;
            int height = encodedImageLabel.getHeight() - 20;
            HashMap<EncodeHintType, String> hints = new HashMap<>();
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            BitMatrix bitMatrix = new QRCodeWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints);
            qrcodeBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            for (int y = 0; y < height; ++y) {
                for (int x = 0; x < width; ++x) {
                    Color color = bitMatrix.get(x, y) ? Color.BLACK : Color.WHITE;
                    qrcodeBufferedImage.setRGB(x, y, color.getRGB());
                }
            }
            encodedImageLabel.setIcon(new ImageIcon(qrcodeBufferedImage));
        } catch (WriterException ex) {
            LOGGER.log(Level.SEVERE, null, ex);
            JOptionPane.showMessageDialog(this, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void onChooseButtonClicked() {
        PicFileChooser picFileChooser = new PicFileChooser();
        if (picFileChooser.showOpenDialog(this) == PicFileChooser.APPROVE_OPTION) {
            qrcodePicFilename = picFileChooser.getSelectedFile().getAbsolutePath();
            qrcodeToDecodeLabel.setIcon(new ImageIcon(qrcodePicFilename));
        }
    }

    private void onDecodeButtonClicked() {
        try {
            BufferedImage qrcodeToDecodeBufferedImage;
            if (qrcodePicFilename == null) {
                qrcodeToDecodeBufferedImage = ImageIO.read(MainFrame.class.getResource("/images/author.jpg"));
            } else {
                qrcodeToDecodeBufferedImage = ImageIO.read(new File(qrcodePicFilename));
            }
            BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(qrcodeToDecodeBufferedImage);
            String decodedText = new QRCodeReader().decode(new BinaryBitmap(new HybridBinarizer(source))).getText();
            decodedResultTextArea.setText(decodedText);
        } catch (ChecksumException | FormatException | NotFoundException | IOException ex) {
            LOGGER.log(Level.SEVERE, null, ex);
            if (ex instanceof NotFoundException) {
                JOptionPane.showMessageDialog(this, "QR code not found", "Error", JOptionPane.ERROR_MESSAGE);
            } else {
                JOptionPane.showMessageDialog(this, "Cannot decode the QR code", "Unknown Error", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    private void onContactAuthorButtonClicked() {
        try {
            Desktop.getDesktop().browse(URI.create("tencent://message/?uin=980639902"));
        } catch (IOException ex) {
            LOGGER.log(Level.SEVERE, null, ex);
        }
    }

    private void onEncodedImageLabelClicked(MouseEvent ev) {
        if (ev.getButton() == MouseEvent.BUTTON3) {
            popupMenu.show(encodedImageLabel, ev.getX(), ev.getY());
        }
    }

    private void onCopyMenuItemClicked() {
        if (qrcodeBufferedImage != null) {
            ImageSelection contents = new ImageSelection(qrcodeBufferedImage);
            Toolkit.getDefaultToolkit().getSystemClipboard().setContents(contents, null);
            TipDialog tipDialog = new TipDialog(this, "Copied to clipboard", 150, 30);
            tipDialog.show(1500);
        }
    }

    private void onSaveMenuItemClicked() {
        if (qrcodeBufferedImage != null) {
            JFileChooser fileChooser = new JFileChooser();
            fileChooser.setFileFilter(new FileNameExtensionFilter("PNG (*.png)", "png"));
            fileChooser.setFileFilter(new FileNameExtensionFilter("Bitmap Files (*.bmp)", "bmp"));
            fileChooser.setAcceptAllFileFilterUsed(false);
            if (fileChooser.showSaveDialog(this) == PicFileChooser.APPROVE_OPTION) {
                try {
                    String formatName;
                    if (fileChooser.getFileFilter().getDescription().equals("PNG (*.png)")) {
                        formatName = "png";
                    } else {
                        formatName = "bmp";
                    }
                    File destinationFile = new File(fileChooser.getSelectedFile() + "." + formatName);
                    if (ImageIO.write(qrcodeBufferedImage, formatName, destinationFile)) {
                        TipDialog tipDialog = new TipDialog(this, "Saved to disk", 150, 30);
                        tipDialog.show(1500);
                    }
                } catch (IOException ex) {
                    LOGGER.log(Level.SEVERE, null, ex);
                }
            }
        }
    }

    public static void main(String[] args) {
        MainFrame mainFrame = new MainFrame();
        mainFrame.setVisible(true);
    }
}

ImageSelection.java

package com.wolf_pan;

import java.awt.Image;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;

public class ImageSelection implements Transferable {

    private final Image image;

    public ImageSelection(Image image) {
        this.image = image;
    }

    @Override
    public DataFlavor[] getTransferDataFlavors() {
        return new DataFlavor[]{DataFlavor.imageFlavor};
    }

    @Override
    public boolean isDataFlavorSupported(DataFlavor flavor) {
        return flavor.equals(DataFlavor.imageFlavor);
    }

    @Override
    public Image getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
        if (!isDataFlavorSupported(flavor)) {
            throw new UnsupportedFlavorException(flavor);
        }
        return image;
    }
}

HintTextArea.java

package com.wolf_pan;

import java.awt.Color;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JTextArea;

public class HintTextArea extends JTextArea {
    public HintTextArea(String hint, int rows) {
        super(hint, rows, 0);
        super.setForeground(Color.GRAY);
        super.addFocusListener(new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {
                if (getForeground() == Color.GRAY && hint.equals(getText())) {
                    setText(null);
                    setForeground(Color.BLACK);
                }
            }

            @Override
            public void focusLost(FocusEvent e) {
                if (getText().equals("")) {
                    setText(hint);
                    setForeground(Color.GRAY);
                }
            }
        });
    }
}
原文地址:https://www.cnblogs.com/buyishi/p/9310302.html