Java实现二维码案例

wen java案例 3

本文目录导读:

Java实现二维码案例

  1. 环境准备
  2. 二维码生成工具类
  3. 二维码解析工具类
  4. 测试用例
  5. 简单的生成界面示例(Swing)
  6. 高级功能示例
  7. 使用说明

我来为您提供一个完整的Java二维码生成和解析案例,使用ZXing库实现。

环境准备

Maven依赖

<dependencies>
    <!-- ZXing 核心库 -->
    <dependency>
        <groupId>com.google.zxing</groupId>
        <artifactId>core</artifactId>
        <version>3.5.2</version>
    </dependency>
    <!-- ZXing JavaSE 扩展库 -->
    <dependency>
        <groupId>com.google.zxing</groupId>
        <artifactId>javase</artifactId>
        <version>3.5.2</version>
    </dependency>
</dependencies>

二维码生成工具类

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
/**
 * 二维码生成工具类
 */
public class QRCodeUtil {
    // 二维码颜色
    private static final int BLACK = 0xFF000000;
    // 二维码背景色
    private static final int WHITE = 0xFFFFFFFF;
    /**
     * 生成二维码(返回BufferedImage)
     */
    public static BufferedImage createQRCode(String content, int width, int height) 
            throws Exception {
        Map<EncodeHintType, Object> hints = new HashMap<>();
        // 设置编码类型
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        // 设置纠错等级(L-低, M-中, Q-较高, H-高)
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        // 设置边距(白边)
        hints.put(EncodeHintType.MARGIN, 1);
        // 生成二维码矩阵
        BitMatrix bitMatrix = new MultiFormatWriter()
                .encode(content, BarcodeFormat.QR_CODE, width, height, hints);
        // 创建图片
        BufferedImage image = new BufferedImage(width, height, 
                BufferedImage.TYPE_INT_RGB);
        // 绘制二维码
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, bitMatrix.get(x, y) ? BLACK : WHITE);
            }
        }
        return image;
    }
    /**
     * 生成带Logo的二维码
     */
    public static BufferedImage createQRCodeWithLogo(String content, int width, 
            int height, BufferedImage logoImage) throws Exception {
        // 先生成普通二维码
        BufferedImage qrImage = createQRCode(content, width, height);
        if (logoImage != null) {
            // 计算Logo大小(约为二维码的1/5)
            int logoSize = width / 5;
            // 创建Graphics2D对象
            Graphics2D g2d = qrImage.createGraphics();
            // 设置Logo位置
            int x = (width - logoSize) / 2;
            int y = (height - logoSize) / 2;
            // 绘制圆角背景
            RoundRectangle2D roundedRect = new RoundRectangle2D.Float(
                    x - 2, y - 2, logoSize + 4, logoSize + 4, 20, 20);
            g2d.setColor(Color.WHITE);
            g2d.fill(roundedRect);
            // 设置抗锯齿
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
                    RenderingHints.VALUE_ANTIALIAS_ON);
            // 绘制Logo
            Image logo = logoImage.getScaledInstance(logoSize, logoSize, 
                    Image.SCALE_SMOOTH);
            g2d.drawImage(logo, x, y, null);
            // 设置边框
            g2d.setColor(Color.LIGHT_GRAY);
            g2d.setStroke(new BasicStroke(2));
            g2d.draw(roundedRect);
            g2d.dispose();
        }
        return qrImage;
    }
    /**
     * 生成二维码到文件
     */
    public static void createQRCodeToFile(String content, int width, int height, 
            File outputFile) throws Exception {
        BufferedImage image = createQRCode(content, width, height);
        // 根据文件后缀判断格式
        String fileName = outputFile.getName();
        String format = fileName.substring(fileName.lastIndexOf(".") + 1);
        ImageIO.write(image, format, outputFile);
    }
    /**
     * 生成二维码到输出流
     */
    public static void createQRCodeToStream(String content, int width, int height, 
            OutputStream outputStream, String format) throws Exception {
        BufferedImage image = createQRCode(content, width, height);
        ImageIO.write(image, format, outputStream);
    }
    /**
     * 生成带Logo的二维码到文件
     */
    public static void createQRCodeWithLogoToFile(String content, int width, 
            int height, File logoFile, File outputFile) throws Exception {
        BufferedImage logoImage = ImageIO.read(logoFile);
        BufferedImage image = createQRCodeWithLogo(content, width, height, logoImage);
        String fileName = outputFile.getName();
        String format = fileName.substring(fileName.lastIndexOf(".") + 1);
        ImageIO.write(image, format, outputFile);
    }
}

二维码解析工具类

import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
/**
 * 二维码解析工具类
 */
public class QRCodeParser {
    /**
     * 解析图片中的二维码
     */
    public static String parseQRCode(BufferedImage image) throws Exception {
        if (image == null) {
            throw new IllegalArgumentException("图片不能为空");
        }
        // 转换图像数据
        LuminanceSource source = new BufferedImageLuminanceSource(image);
        BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
        // 设置解码提示
        Map<DecodeHintType, Object> hints = new HashMap<>();
        hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
        // 解码二维码
        MultiFormatReader reader = new MultiFormatReader();
        Result result = reader.decode(bitmap, hints);
        return result.getText();
    }
    /**
     * 解析文件中的二维码
     */
    public static String parseQRCodeFromFile(File file) throws Exception {
        BufferedImage image = ImageIO.read(file);
        return parseQRCode(image);
    }
    /**
     * 从输入流解析二维码
     */
    public static String parseQRCodeFromStream(InputStream inputStream) 
            throws Exception {
        BufferedImage image = ImageIO.read(inputStream);
        return parseQRCode(image);
    }
    /**
     * 解析二维码,返回详细结果
     */
    public static Result parseQRCodeDetail(BufferedImage image) throws Exception {
        LuminanceSource source = new BufferedImageLuminanceSource(image);
        BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
        Map<DecodeHintType, Object> hints = new HashMap<>();
        hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
        MultiFormatReader reader = new MultiFormatReader();
        return reader.decode(bitmap, hints);
    }
}

测试用例

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
/**
 * 测试类
 */
public class QRCodeTest {
    public static void main(String[] args) {
        try {
            // 测试1:生成简单二维码
            String content = "https://www.example.com";
            File qrFile = new File("qr_code.png");
            QRCodeUtil.createQRCodeToFile(content, 300, 300, qrFile);
            // 解析二维码
            String parsedContent = QRCodeParser.parseQRCodeFromFile(qrFile);
            System.out.println("解析结果: " + parsedContent);
            System.out.println("验证成功: " + content.equals(parsedContent));
            // 测试2:生成带Logo的二维码
            // 创建简单的Logo(纯色图片)
            BufferedImage logo = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = logo.createGraphics();
            g2d.setColor(Color.RED);
            g2d.fillOval(10, 10, 80, 80);
            g2d.setColor(Color.WHITE);
            g2d.setFont(new Font("Arial", Font.BOLD, 30));
            g2d.drawString("LOGO", 15, 60);
            g2d.dispose();
            File logoFile = new File("qr_code_with_logo.png");
            QRCodeUtil.createQRCodeWithLogoToFile(content, 300, 300, logo, logoFile);
            // 解析带Logo的二维码
            BufferedImage qrImage = ImageIO.read(logoFile);
            String parsedLogoContent = QRCodeParser.parseQRCode(qrImage);
            System.out.println("带Logo二维码解析结果: " + parsedLogoContent);
            // 测试3:不同大小的二维码
            File smallQR = new File("qr_code_small.png");
            QRCodeUtil.createQRCodeToFile("Hello World", 150, 150, smallQR);
            // 测试4:编码中文内容
            File chineseQR = new File("qr_code_chinese.png");
            String chineseContent = "你好,世界!";
            QRCodeUtil.createQRCodeToFile(chineseContent, 200, 200, chineseQR);
            String parsedChinese = QRCodeParser.parseQRCodeFromFile(chineseQR);
            System.out.println("中文内容解析: " + parsedChinese);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

简单的生成界面示例(Swing)

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
/**
 * 简单的二维码生成界面
 */
public class QRCodeUI extends JFrame {
    private JTextField contentField;
    private JTextField sizeField;
    private JButton generateBtn;
    private JLabel qrLabel;
    public QRCodeUI() {
        setTitle("二维码生成器");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout(10, 10));
        // 创建输入面板
        JPanel inputPanel = new JPanel(new GridLayout(3, 2, 10, 10));
        inputPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        inputPanel.add(new JLabel("二维码内容:"));
        contentField = new JTextField();
        inputPanel.add(contentField);
        inputPanel.add(new JLabel("二维码大小(px):"));
        sizeField = new JTextField("300");
        inputPanel.add(sizeField);
        generateBtn = new JButton("生成二维码");
        inputPanel.add(generateBtn);
        inputPanel.add(new JLabel(""));
        add(inputPanel, BorderLayout.NORTH);
        // 创建显示区域
        qrLabel = new JLabel("", SwingConstants.CENTER);
        qrLabel.setBorder(BorderFactory.createLineBorder(Color.GRAY));
        add(qrLabel, BorderLayout.CENTER);
        // 添加生成按钮事件
        generateBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                generateQRCode();
            }
        });
        setSize(500, 500);
        setLocationRelativeTo(null);
        setVisible(true);
    }
    private void generateQRCode() {
        try {
            String content = contentField.getText();
            int size = Integer.parseInt(sizeField.getText());
            if (content.isEmpty()) {
                JOptionPane.showMessageDialog(this, "请输入二维码内容!");
                return;
            }
            // 生成二维码
            BufferedImage qrImage = QRCodeUtil.createQRCode(content, size, size);
            // 显示二维码
            ImageIcon icon = new ImageIcon(qrImage);
            qrLabel.setIcon(icon);
            // 保存到文件
            JFileChooser fileChooser = new JFileChooser();
            fileChooser.setSelectedFile(new File("qr_code.png"));
            if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
                File outputFile = fileChooser.getSelectedFile();
                QRCodeUtil.createQRCodeToFile(content, size, size, outputFile);
                JOptionPane.showMessageDialog(this, "二维码保存成功!");
            }
        } catch (NumberFormatException ex) {
            JOptionPane.showMessageDialog(this, "请输入有效的大小!");
        } catch (Exception ex) {
            ex.printStackTrace();
            JOptionPane.showMessageDialog(this, "生成失败: " + ex.getMessage());
        }
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new QRCodeUI();
            }
        });
    }
}

高级功能示例

import com.google.zxing.common.BitMatrix;
/**
 * 高级功能示例
 */
public class QRCodeAdvanced {
    /**
     * 生成彩色二维码
     */
    public static BufferedImage createColoredQRCode(String content, int width, 
            int height, int foregroundColor, int backgroundColor) throws Exception {
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        BitMatrix bitMatrix = new MultiFormatWriter()
                .encode(content, BarcodeFormat.QR_CODE, width, height, hints);
        BufferedImage image = new BufferedImage(width, height, 
                BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, bitMatrix.get(x, y) ? foregroundColor : backgroundColor);
            }
        }
        return image;
    }
    /**
     * 生成带渐变效果的二维码
     */
    public static BufferedImage createGradientQRCode(String content, int width, 
            int height, Color startColor, Color endColor) throws Exception {
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        BitMatrix bitMatrix = new MultiFormatWriter()
                .encode(content, BarcodeFormat.QR_CODE, width, height, hints);
        BufferedImage image = new BufferedImage(width, height, 
                BufferedImage.TYPE_INT_RGB);
        // 创建渐变
        GradientPaint gradient = new GradientPaint(
                0, 0, startColor, 
                width, height, endColor);
        Graphics2D g2d = image.createGraphics();
        g2d.setPaint(Color.WHITE);
        g2d.fillRect(0, 0, width, height);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                if (bitMatrix.get(x, y)) {
                    // 根据位置计算颜色
                    float ratio = (float)(x + y) / (width + height);
                    Color pixelColor = interpolateColor(startColor, endColor, ratio);
                    image.setRGB(x, y, pixelColor.getRGB());
                }
            }
        }
        g2d.dispose();
        return image;
    }
    private static Color interpolateColor(Color c1, Color c2, float ratio) {
        int r = (int)(c1.getRed() * (1 - ratio) + c2.getRed() * ratio);
        int g = (int)(c1.getGreen() * (1 - ratio) + c2.getGreen() * ratio);
        int b = (int)(c1.getBlue() * (1 - ratio) + c2.getBlue() * ratio);
        return new Color(r, g, b);
    }
}

使用说明

  1. 基础使用

    • 使用 QRCodeUtil.createQRCodeToFile() 生成二维码文件
    • 使用 QRCodeParser.parseQRCodeFromFile() 解析二维码
  2. 功能特性

    • 支持自定义大小和颜色
    • 支持添加Logo
    • 支持中英文内容
    • 可设置不同的纠错级别
  3. 常见应用场景

    • 商品信息链接
    • 支付二维码
    • 身份验证
    • 活动宣传
    • 电子票务

这个案例提供了完整的二维码解决方案,您可以根据实际需求进行调整和扩展。

抱歉,评论功能暂时关闭!