QR Code

前言

  • QR Code 码,是由 Denso 公司于 1994 年 9 月研制的一种矩阵二维码符号,它具有一维条码及其它二维条码所具有的信息容量大、可靠性高、可表示汉字及图象多种文字信息、保密防伪性强等优点。

  • 从 QR Code 码的英文名称 Quick Response Code 可以看出,超高速识读特点是 QR Code 码区别于四一七条码、Data Matrix 等二维码的主要特性。由于在用 CCD 识读 QR Code 码时,整个 QR Code 码符号中信息的读取是通过 QR Code 码符号的位置探测图形,用硬件来实现,因此,信息识读过程所需时间很短,它具有超高速识读特点。用 CCD 二维条码识读设备,每秒可识读 30 个含有 100 个字符的 QR Code 码符号;对于含有相同数据信息的四一七条码符号,每秒仅能识读 3 个符号;对于 Data Matrix 矩阵码,每秒仅能识读 2~3 个符号。QR Code 码的超高速识读特性使它能够广泛应用于工业自动化生产线管理等领域。

  • QR Code 码具有全方位(360°)识读特点,这是 QR Code 码优于行排式二维条码如四一七条码的另一主要特点,由于四一七条码是将一维条码符号在行排高度上的截短来实现的,因此它很难实现全方位识读,其识读方位角仅为 ±10°。

  • 由于 QR Code 码用特定的数据压缩模式表示汉字,它仅用 13bit 可表示一个汉字,而四一七条码、Data Matrix 等二维码没有特定的汉字表示模式,因此仅用字节表示模式来表示汉字,在用字节模式表示汉字时,需用 16bit(二个字节)表示一个汉字,因此 QR Code 码比其它的二维条码表示汉字的效率提高了 20%。

  • QR Code 生成原理及解析

1、Java 创建/解析二维码

  • Java 创建/解析二维码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    import java.awt.Color;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;

    import javax.imageio.ImageIO;

    import com.swetake.util.Qrcode;

    import jp.sourceforge.qrcode.QRCodeDecoder;
    import jp.sourceforge.qrcode.data.QRCodeImage;
    import jp.sourceforge.qrcode.exception.DecodingFailedException;

    public class QRCodeUtil {

    /**
    * 创建二维码,把字符串写进二维码,并且生成图片到 destFile
    *
    * @param encodeddata
    * @param destFile
    */
    public static void qrCodeEncode(String encodeddata, File destFile) throws IOException {
    Qrcode qrcode = new Qrcode();
    qrcode.setQrcodeErrorCorrect('M'); // 纠错级别(L 7%、M 15%、Q 25%、H 30%)和版本有关
    qrcode.setQrcodeEncodeMode('B');
    qrcode.setQrcodeVersion(7); // 设置 Qrcode 包的版本

    byte[] d = encodeddata.getBytes("GBK"); // 字符集
    BufferedImage bi = new BufferedImage(139, 139, BufferedImage.TYPE_INT_RGB);
    // createGraphics // 创建图层
    Graphics2D g = bi.createGraphics();

    g.setBackground(Color.WHITE); // 设置背景颜色(白色)
    g.clearRect(0, 0, 139, 139); // 矩形 X、Y、width、height
    g.setColor(Color.BLACK); // 设置图像颜色(黑色)

    if (d.length > 0 && d.length < 123) {
    boolean[][] b = qrcode.calQrcode(d);
    for (int i = 0; i < b.length; i++) {
    for (int j = 0; j < b.length; j++) {
    if (b[j][i]) {
    g.fillRect(j * 3 + 2, i * 3 + 2, 3, 3);
    }
    }
    }
    }

    // Image img = ImageIO.read(new File("D:/tt.png")); logo
    // g.drawImage(img, 25, 55,60,50, null);

    g.dispose(); // 释放此图形的上下文以及它使用的所有系统资源。调用 dispose 之后,就不能再使用 Graphics 对象
    bi.flush(); // 刷新此 Image 对象正在使用的所有可重构的资源

    ImageIO.write(bi, "png", destFile);
    // System.out.println("Input Encoded data is:" + encodeddata);
    }

    /**
    * 解析二维码,把二维码信息从 imageFile 中读取出来,返回解析内容
    *
    * @param imageFile
    * @return
    */
    public static String qrCodeDecode(File imageFile) {
    String decodedData = null;
    QRCodeDecoder decoder = new QRCodeDecoder();
    BufferedImage image = null;
    try {
    image = ImageIO.read(imageFile);
    } catch (IOException e) {
    System.out.println("Error: " + e.getMessage());
    }

    try {
    decodedData = new String(decoder.decode(new J2SEImage(image)), "GBK");
    // System.out.println("Output Decoded Data is:" + decodedData);
    } catch (DecodingFailedException dfe) {
    System.out.println("Error: " + dfe.getMessage());
    } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
    }
    return decodedData;
    }

    static class J2SEImage implements QRCodeImage {
    BufferedImage image;

    public J2SEImage(BufferedImage image) {
    this.image = image;
    }

    public int getWidth() {
    return image.getWidth();
    }

    public int getHeight() {
    return image.getHeight();
    }

    public int getPixel(int x, int y) {
    return image.getRGB(x, y);
    }
    }

    public static void main(String[] args) {
    String filePath = "d:/qrcode.png";
    File qrFile = new File(filePath);

    // 二维码内容
    String encodeddata = "https://www.qianchia.com";
    try {
    // 编码
    QRCodeUtil.qrCodeEncode(encodeddata, qrFile);
    } catch (IOException e) {
    e.printStackTrace();
    }

    // 解码
    String reText = QRCodeUtil.qrCodeDecode(qrFile);
    System.out.println(reText);
    }
    }

2、Javascript 创建/解析二维码

  • Javascript 创建/解析二维码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    <!DOCTYPE html>
    <html>

    <head>
    <meta charset="utf-8" />
    <title>Qian Chia 工作室</title>

    <script src="https://repo.qianchia.com/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://repo.qianchia.com/jquery/qrcode/1.0/jquery.qrcode.min.js"></script>
    </head>

    <body>
    <div style="width: 800px; margin: 50px auto; text-align: center">
    <h1>把字符串: https://www.qianchia.com 转换为二维码</h1>
    <div id="qrcode"></div>
    </div>

    <script>
    $(function () {
    $('#qrcode').qrcode({ render: 'canvas', text: "https://www.qianchia.com", width: 260, height: 260 });
    });
    </script>
    </body>

    </html>
文章目录
  1. 1. 前言
  2. 2. 1、Java 创建/解析二维码
  3. 3. 2、Javascript 创建/解析二维码
隐藏目录