微信小程序生成二维码
感觉这个没什么好写的,不知道哪天开的这个文章的头,寻思文件都创建了就补完吧。
普通二维码
我们使用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');
},
然后就有一个能看出来的二维码了
手动实现二维码
整点儿有用的,二维码的核心编码逻辑
二维码生成遵循 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>
然后就获得了一个非常潦草的二维码,虽然是有详细的框架和现成的算法,但毕竟不是搞密码学的,大概意思先了解了一下,等有了需求之后再说