Quiet
  • 主页
  • 归档
  • 分类
  • 标签
  • 链接
  • 关于我

bajiu

  • 主页
  • 归档
  • 分类
  • 标签
  • 链接
  • 关于我
Quiet主题

微信小程序生成二维码

bajiu
前端

2024-11-11 11:50:26

感觉这个没什么好写的,不知道哪天开的这个文章的头,寻思文件都创建了就补完吧。

普通二维码

我们使用weapp-qrcode来生成二维码https://github.com/yingye/weapp-qrcode#readme

好像也没什么好说的,就跟API里一样…

// 绘制二维码实现方法
draw(str) {
    wx.showToast({
        title: '二维码加载中',
        icon: 'loading',
    })
    // console.log('run str', str);
    drawQrcode({
        width: 160,
        height: 160,
        x: 20,
        y: 20,
        canvasId: 'myQrcode',
        // ctx: wx.createCanvasContext('myQrcode'),
        typeNumber: 10,
        text: str,
        image: {
        imageResource: '../../../image/logo.png',
        dx: 70,
        dy: 70,
        dWidth: 60,
        dHeight: 60
        },
        callback(e) {
        // console.log('e: ', e)
        wx.hideToast()
        }
    })
    //console.log('run draw');
},

然后就有一个能看出来的二维码了
qrCode1

手动实现二维码

整点儿有用的,二维码的核心编码逻辑

二维码生成遵循 QR Code 的国际标准(ISO/IEC 18004)。主要步骤包括:

1.数据编码

将输入数据编码成 QR Code 规范的数据流:

  • 模式选择:根据数据内容选择模式(数字模式、字母模式、字节模式等)。
  • 数据分块:将数据分割为多个小块。
  • 数据编码:使用 QR Code 的数据格式(如模式指示符、字符数指示符等)。

2.错误校正

QR Code 使用 Reed-Solomon 算法添加冗余数据,用于错误修正。你需要实现或使用已有的 Reed-Solomon 编码函数。

3.数据填充

将编码后的数据填充到二维码矩阵中,包括定位图形、校正图形和实际数据。

大概实现一下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>生成二维码</title>
</head>
<body>
    <canvas id="qrcode" width="300" height="300" style="border: 1px solid black;"></canvas>

    <script>
        // 二维码数据编码
        function encodeData(data) {
            const binaryData = [];
            for (let i = 0; i < data.length; i++) {
                const binary = data.charCodeAt(i).toString(2).padStart(8, '0'); // 转为8位二进制
                binaryData.push(binary);
            }
            return binaryData.join('');
        }
        // 生成二维码矩阵
        function createMatrix(size) {
            // 初始化矩阵
            const matrix = Array.from({ length: size }, () => Array(size).fill(0));
            // 添加定位图形
            addFinderPattern(matrix, 0, 0); // 左上角
            addFinderPattern(matrix, size - 7, 0); // 左下角
            addFinderPattern(matrix, 0, size - 7); // 右上角
            return matrix;
        }

        function addFinderPattern(matrix, x, y) {
            // 定位图形:7x7 的正方形
            for (let i = 0; i < 7; i++) {
                for (let j = 0; j < 7; j++) {
                    matrix[x + i][y + j] = (i === 0 || i === 6 || j === 0 || j === 6 || (i >= 2 && i <= 4 && j >= 2 && j <= 4)) ? 1 : 0;
                }
            }
        }
        // 数据填充
        function fillData(matrix, binaryData) {
            const size = matrix.length;
            let dataIndex = 0;

            for (let col = size - 1; col > 0; col -= 2) {
                if (col === 6) col--; // 跳过定位图形的列
                for (let row = 0; row < size; row++) {
                    for (let offset = 0; offset < 2; offset++) {
                        const x = col - offset;
                        const y = row;
                        if (matrix[y][x] === 0 && dataIndex < binaryData.length) {
                            matrix[y][x] = binaryData[dataIndex] === '1' ? 1 : 0;
                            dataIndex++;
                        }
                    }
                }
            }
        }

        // Canvas 绘制二维码矩阵
        function drawQRCode(matrix, canvasId) {
            const canvas = document.getElementById(canvasId);
            const ctx = canvas.getContext('2d');
            const size = matrix.length;
            const cellSize = canvas.width / size;

            for (let i = 0; i < size; i++) {
                for (let j = 0; j < size; j++) {
                    ctx.fillStyle = matrix[i][j] === 1 ? '#000000' : '#FFFFFF';
                    ctx.fillRect(j * cellSize, i * cellSize, cellSize, cellSize);
                }
            }
        }

        const data = "Hello, QR!";
        const binaryData = encodeData(data);
        const matrixSize = 21; // 最小版本
        const matrix = createMatrix(matrixSize);
        fillData(matrix, binaryData);
        drawQRCode(matrix, "qrcode");
    </script>
</body>
</html>

然后就获得了一个非常潦草的二维码,虽然是有详细的框架和现成的算法,但毕竟不是搞密码学的,大概意思先了解了一下,等有了需求之后再说

qrCode2

上一篇

HTTP/3详解

下一篇

react实现类似GPT的对话应用

©2024 By bajiu.