首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 二維碼生成與解析:基於 QRCode.jar 經典實現完整代碼

     編輯:Java 相關知識

技術棧

  • QRCode.jar:日本スウェテーク開發的經典 QR Code 庫(SourceForge.jp 託管)
  • 純 Java 實現,無原生依賴,輕量級(~100KB)

Maven 依賴(手動安裝到本地倉庫)

mvn install:install-file -Dfile=QRCode.jar -DgroupId=jp.sourceforge.qrcode -DartifactId=qrcode -Dversion=1.0 -Dpackaging=jar

核心類:TwoDimensionCode

package qrcode;

import com.swetake.util.Qrcode;
import jp.sourceforge.qrcode.QRCodeDecoder;
import jp.sourceforge.qrcode.exception.DecodingFailedException;
import jp.sourceforge.qrcode.data.QRCodeImage;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

public class TwoDimensionCode {

    /** 生成二維碼到文件 */
    public void encoderQRCode(String content, String imgPath) {
        encoderQRCode(content, imgPath, "png", 7);
    }

    public void encoderQRCode(String content, OutputStream output) {
        encoderQRCode(content, output, "png", 7);
    }

    public void encoderQRCode(String content, String imgPath, String imgType, int size) {
        try {
            BufferedImage bufImg = qRCodeCommon(content, imgType, size);
            ImageIO.write(bufImg, imgType, new File(imgPath));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void encoderQRCode(String content, OutputStream output, String imgType, int size) {
        try {
            BufferedImage bufImg = qRCodeCommon(content, imgType, size);
            ImageIO.write(bufImg, imgType, output);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /** 核心繪製邏輯 */
    private BufferedImage qRCodeCommon(String content, String imgType, int size) {
        Qrcode handler = new Qrcode();
        handler.setQrcodeErrorCorrect('M');      // M級 15% 容錯
        handler.setQrcodeEncodeMode('B');        // Byte 模式
        handler.setQrcodeVersion(size);          // 1-40 版本

        byte[] contentBytes = content.getBytes(StandardCharsets.UTF_8);
        int imgSize = 67 + 12 * (size - 1);      // 計算圖片邊長
        BufferedImage bufImg = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB);
        Graphics2D gs = bufImg.createGraphics();
        gs.setBackground(Color.WHITE);
        gs.clearRect(0, 0, imgSize, imgSize);
        gs.setColor(Color.BLACK);

        int pixoff = 2; // 偏移量,關鍵參數,影響解析成功率
        if (contentBytes.length > 0 && contentBytes.length < 800) {
            boolean[][] codeOut = handler.calQrcode(contentBytes);
            for (int i = 0; i < codeOut.length; i++) {
                for (int j = 0; j < codeOut.length; j++) {
                    if (codeOut[j][i]) {
                        gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);
                    }
                }
            }
        } else {
            throw new IllegalArgumentException("內容長度需在 1-800 字節之間");
        }
        gs.dispose();
        bufImg.flush();
        return bufImg;
    }

    /** 解析二維碼文件 */
    public String decoderQRCode(String imgPath) {
        try {
            BufferedImage bufImg = ImageIO.read(new File(imgPath));
            QRCodeDecoder decoder = new QRCodeDecoder();
            return new String(decoder.decode(new TwoDimensionCodeImage(bufImg)), "UTF-8");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public String decoderQRCode(InputStream input) {
        try {
            BufferedImage bufImg = ImageIO.read(input);
            QRCodeDecoder decoder = new QRCodeDecoder();
            return new String(decoder.decode(new TwoDimensionCodeImage(bufImg)), "UTF-8");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /** 測試入口 */
    public static void main(String[] args) {
        String path = "G:/QRCode.png";
        String content = "Hello QRCode!\nBlog: https://example.com\nEmail: test@example.com";

        TwoDimensionCode handler = new TwoDimensionCode();
        handler.encoderQRCode(content, path, "png", 7);
        System.out.println("生成成功");

        String decoded = handler.decoderQRCode(path);
        System.out.println("解析結果:\n" + decoded);
    }
}

輔助類:TwoDimensionCodeImage

package qrcode;

import jp.sourceforge.qrcode.data.QRCodeImage;
import java.awt.image.BufferedImage;

public class TwoDimensionCodeImage implements QRCodeImage {
    private final BufferedImage bufImg;

    public TwoDimensionCodeImage(BufferedImage bufImg) {
        this.bufImg = bufImg;
    }

    @Override public int getWidth()  { return bufImg.getWidth(); }
    @Override public int getHeight() { return bufImg.getHeight(); }
    @Override public int getPixel(int x, int y) { return bufImg.getRGB(x, y); }
}

關鍵參數說明

參數範圍/選項影響
ErrorCorrectL(7%) M(15%) Q(25%) H(30%)容錯越高,可存內容越少,但抗污損能力越強
EncodeModeN(數字) A(字母數字) B(8-bit字節) K(日文)B 模式通用性最強,支持中文 UTF-8
Version1-40版本越大,矩陣越大,容量越高
pixoff建議 2模塊繪製偏移,太小邊緣模糊,太大超出畫布
模塊像素固定 3x3每個邏輯模塊對應 3x3 物理像素,影響最終圖片尺寸

優缺點對比

維度QRCode.jarZXing
Jar 體積~100KBcore ~500KB + javase ~300KB
API 設計簡單直接功能豐富,支持多格式、多平台
Logo 嵌入需自行繪製社區有成熟封裝
維護狀態多年未更新活躍維護,支持最新 JDK
適用場景輕量、舊項目、無 Logo 需求新項目、多格式、需 Logo/樣式定制
QRCode.jar 適合快速集成、極簡依賴、無花哨需求的老項目;新項目首選 ZXing,生態更完善。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved