一种压缩QRCode矩阵以用于存储的方法

server/2024/10/15 17:50:47/

通常QRCode由服务器生成,以图片格式发送到客户端,由客户端直接展示,也可以由客户端使用javascript或其他内置的SDK直接生成。

0、需求

QRCode生成过程中往往是先生成矩阵,然后使用矩阵生成图片,矩阵就是由01组成的一维或二维数组。
例如,由ZXing生成的ByteMatrix就是一个由行列数据组成的二维数组。

//可以生成由01组成的一个矩阵字符串。
private string GetMatrixString(ByteMatrix matrix)
{return string.Join("", matrix.Array.Select(t => string.Join("", t)));
}

有时候,我们需要尽可能的减少网络传输,对QRCode进行缓存处理,或者减少QRCode矩阵生成的逻辑。
这时,我们完全可以将这个字符串发送给客户端,再由客户端生成图片,减少网络浏览传输或者方便客户端缓存QRCode。

下面方法可以对矩阵处理,生成QRCode图片。

javascript">function createQRCodeCanvas(matrix, size, padding) {size = size || 3;padding = padding === undefined ? 3 : padding;const width = Math.sqrt(matrix.length);const canvasWith = width * size + padding * 2;const canvas = document.createElement('canvas');canvas.width = canvasWith;canvas.height = canvasWith;const ctx = canvas.getContext('2d');ctx.fillStyle = "rgb(0,0,0)";for (let y = 0; y < width; y++) {for (let x = 0; x < width; x++) {const point = y * width + x;if (matrix[point] === 1) {ctx.fillRect(padding + x * size, padding + y * size, size, size);}}}return canvas.toDataURL();
}
1、矩阵压缩

由于矩阵完全由01组成,我们可以对矩阵进行处理,每8位作为一组,转换成一个字节。
往往矩阵的长度不会被8整除,所以我们在最后一位补1,标识矩阵结束,哪怕矩阵长度能被8整除,我们也补1。
下面代码生成压缩后的矩阵字节数组。

private byte[] GetMatrixBytes(ByteMatrix matrix)
{var qrData = matrix.Array;int idx = 7;int count = 0;byte[] result = new byte[(int)Math.Ceiling((decimal)(qrData.Length * qrData.Length + 1) / 8)];for (int i = 0; i < qrData.Length; i++){byte[] line = qrData[i];for (int j = 0; j < line.Length; j++){result[count++ >> 3] |= (byte)(line[j] << idx--);if (idx == -1) idx = 7;}}result[count >> 3] |= (byte)(1 << idx); //最后一位补1return result;
}

生成矩阵字节数组后,可以转换成base64发送到客户端,这样会大大减少传输的数据量。

2、矩阵还原

将上面的算法逆转即可。
例如,用csharp还原。

/// <summary>
/// 从字节数组还原矩阵字符串
/// </summary>
/// <param name="matrix"></param>
/// <returns></returns>
private byte[] GetMatrixBytes(byte[] matrix)
{byte[] bytes = new byte[matrix.Length * 8];int idx = 0;foreach (byte chr in matrix) for (int i = 7; i >= 0; i--) bytes[idx++] = (byte)((chr >> i) & 1);while (bytes[--idx] == 0) ;return bytes.Take(idx).ToArray();
}

javascript还原

javascript">function getMatrix(raws) {const bytes = [];let idx = 0;for (let j = 0; j < raws.length; j++) {for (let i = 7; i >= 0; i--) bytes[idx++] = (raws[j] >> i) & 1;}while (bytes[--idx] === 0) ;return bytes.slice(0, idx);
}

矩阵还原出来后,就可以用文章最开始的方法将矩阵生成图片了。

3、总结

通过对矩阵的处理,进一步减少标识矩阵所用的字节数,从而减少网络传输的数据,并且更方便的缓存生成的QRCode。
客户端可以只缓存压缩后的矩阵,必要的时候还原并展示即可。

在这里插入图片描述


http://www.ppmy.cn/server/132294.html

相关文章

瑞芯微RK3566/RK3568 Android11使用OTA升级固件方法,深圳触觉智能鸿蒙开发板演示,备战第九届华为ICT大赛

本文介绍瑞芯微RK3566/RK3568在Android11系统OTA升级固件方法&#xff0c;使用触觉智能的Purple Pi OH鸿蒙开发板演示&#xff0c;搭载了瑞芯微RK3566&#xff0c;Laval官方社区主荐&#xff01; 1、OTA包生成 在源码根目录上执行以下命令编译OTA包 # make installclean # …

python对weedfs的操作

1、weedfs的简介 如果你对weed储存有一定的理解也可以忽略 WeedFS&#xff08;Weed File System&#xff09;是一个开源的分布式文件系统&#xff0c;由Go语言编写&#xff0c;旨在解决海量文件存储和访问的问题。它采用了类似于Hadoop HDFS的分布式文件系统架构&#xff0c;…

载货车一键启动无钥匙进入、手机也能控制、这配置真高端

‌货车一键启动功能的核心作用是通过一个按钮实现车辆的启动和熄火&#xff0c;极大地简化了传统钥匙启动的繁琐步骤&#xff0c;提高了使用的便捷性和安全性。‌ 货车一键启动系统的具体功能包括&#xff1a; 无钥匙进入‌&#xff1a;车主只需携带智能钥匙靠近车辆&#xf…

uniappx uts自学(2024/10/14)

uts需要类型 uts声明变量 let 或 const let相当于 TypeScript 中的 let、kotlin 中的 var、swift 中的 var。 cosnt相当于 TypeScript 中的 const、kotlin 中的 val、swift 中的 let。 let [变量名] : [类型] 值; let str :string "hello"; // 声明一个字符串…

Spring Boot学习资源库:Java开发者的新篇章

2 相关技术简介 2.1Java技术 Java是一种非常常用的编程语言&#xff0c;在全球编程语言排行版上总是前三。在方兴未艾的计算机技术发展历程中&#xff0c;Java的身影无处不在&#xff0c;并且拥有旺盛的生命力。Java的跨平台能力十分强大&#xff0c;只需一次编译&#xff0c;任…

几种常用大模型工具生成基于hi3861的OpenHarmony代码的尝试

引言 最近在上智能物联网的课程&#xff0c;讲授基于hi3861的OpenHarmony编程&#xff0c;所以尝试一下使用大模型工具生成相关的代码&#xff0c;看看效果如何。提问的方式比较简单粗暴&#xff1a; 在OpenHarmony的hi3861平台上&#xff0c;如何编程访问https的网站&#xf…

力扣 前缀和

找子数组的个数了解前缀和的基础。 前缀和大致理解为到达某个位置&#xff0c;前面几个数的总和&#xff0c;即s[i1]s[i]a[i1]&#xff0c;可以通过一次循环获得。然后几个前缀和作差&#xff0c;即可得到某个位置到某个位置的和&#xff0c;根据map的键值对进行更新次数。 题…

什么是智能合约?

什么是智能合约&#xff1f; 智能合约&#xff0c;就是一段写在区块链上的代码&#xff0c;一旦某个事件触发合约中的条款&#xff0c;代码即自动执行。也就是说&#xff0c;满足条件就执行&#xff0c;不需要人为操控、不需要第三方信任。区块链的安全性和不可篡改性&#xf…