查看: 576|回复: 0

扩展库使用说明——二维码生成

[复制链接]

19

主题

80

帖子

631

积分

版主

Rank: 7Rank: 7Rank: 7

积分
631
发表于 2021-10-15 15:03:48 | 显示全部楼层 |阅读模式
本帖最后由 blue 于 2021-10-16 21:09 编辑


扩展库说明:
一个用 C生成二维码的简单库,针对处理和内存受限系统进行了优化。
特征:
  • 基于堆栈(不需要堆;但如果需要,可以使用堆)
  • 低内存占用空间(相对)
  • 编译时剥离不必要的逻辑和常量
  • MIT协议


API说明:

  1. QRCode qrcode;// 定义结构体变量
  2.   uint8_t qrcodeData[qrcode_getBufferSize(10)];//分配内存
  3.   qrcode_initText(&qrcode, qrcodeData, 10, 3, "http://twen51.com");//定义二维码版本,纠错等级,内容
复制代码

什么是版本、纠错等级?
二维码由许多称为模块的小方块组成,它们代表编码数据,并具有额外的纠错功能(允许部分损坏的二维码仍可读取)。
的版本的QR码是1和40(含),其指示QR码的大小之间的数字。二维码的宽度和高度总是相等(它是正方形)并且等于4 * version + 17。
纠错级别是 0 到 3(含)之间的数字,或者可以是符号名称 ECC_LOW、ECC_MEDIUM、ECC_QUARTILE 和 ECC_HIGH 之一。更高级别的纠错会牺牲数据容量,但允许更大部分的二维码被损坏或无法读取。
二维码的模式由被编码的数据决定。每个模式都使用紧凑的表示在内部进行编码,因此较低的模式可以包含更多数据。
  • 数字:数字 ( 0-9)
  • 字母A-Z数字:大写字母 ( )、数字 ( 0-9)、空格 ( )、美元符号 ( $)、百分号 ( %)、星号 ( *)、加号 ( +)、减号 ( -)、小数点 ( .)、斜线 ( /) 和冒号 ( .
  • BYTE:任意字符

数据容量
1.jpg 2.jpg 3.jpg 4.jpg 5.jpg 6.jpg 7.jpg 8.jpg 9.jpg

范例程序:
用彩屏显示二维码

SPI显示屏显示二维码图形化版本_1634389854731.png
  1. #include <CH32V103.h>
  2. #include "myLib/CH32V_ST7735S.h"
  3. #include "myLib/QRCode.h"

  4. SPITFT spi_tft(128,128,PC5,PA2,PA4);

  5. int main(void)
  6. {
  7.   CH32_Init();
  8.   
  9.   QRCode qrcode;// Create the QR code
  10.   uint8_t qr_size = 10;
  11.   uint8_t qrcodeData[qrcode_getBufferSize(qr_size)];
  12.   qrcode_initText(&qrcode, qrcodeData, qr_size, 3, "http://twen51.com");
  13.   uint8_t x0,y0;
  14.   x0 = y0 = (128 - (qr_size*4+17))/2;//居中
  15.   spi_tft.init();
  16.   spi_tft.set_direction(2);
  17.   spi_tft.clear((0xFFFF));

  18.   spi_tft.draw_rectangle(x0-3,y0-3,x0+qr_size*4+17+3,y0+qr_size*4+17+3,(0x0000));//画边框
  19.   for (uint8_t y = 0; y < qrcode.size; y++) {
  20.         // Each horizontal module
  21.         for (uint8_t x = 0; x < qrcode.size; x++) {
  22.             spi_tft.draw_point(x0+x,y0+y,(qrcode_getModule(&qrcode, x, y) ? 0x0000: 0xFFFF));
  23.         }
  24.     }
  25.   while(1){

  26.   }
  27.   return 1;
  28. }
复制代码







二维码知识普及(以下内容来源于网络,如有版权问题,请联系)

二维码又称二维条码,最初在1994年由日本DENSO WAVE公司腾弘原团队发明。

简介
二维码又称二维条码,它是用特定的几何图形按一定规律在平面(二维方向)上分布的黑白相间的图形。相比一维的条码,二维码能够在横向和纵向两个方位同时表达信息,因此能在很小的面积内表达大量的信息,同时可以有较高的容错能力。最初在1994年由日本DENSO WAVE公司腾弘原团队发明,后来DENSO WAVE 公司宣布,不行使本公司就标准QR码拥有的专利权(专利第2938338号),目前,QR码已经在国家标准和国际标准中实现标准化,任何人都可以随意查看该标准。
二维码分类
  • 堆叠式/行排式二维条码
    其编码原理是建立在一维条码基础之上,按需要堆积成二行或多行。它在编码设计、校验原理、识读方式等方面继承了一维条码的一些特点,但由于行数的增加,需要对行进行判定,其译码算法不完全相同于一维条码。有代表性的行排式二维条码有:Code 16K、Code 49、PDF417、MicroPDF417 等。
  • 矩阵式二维码
    最流行的就是QR CODE ,我们常说的二维码大多数都是他。在矩阵相应元素位置上,用点(方点、圆点或其他形状)的出现表示二进制“1”,点的不出现表示二进制的“0”,点的排列组合确定了矩阵式二维条码所代表的意义。矩阵式二维条码是建立在计算机图像处理技术、组合编码原理等基础上的一种新型图形符号自动识读处理码制。具有代表性的矩阵式二维条码有:Code One、MaxiCode、QR Code、 Data Matrix、Han Xin Code、Grid Matrix 等。

QRCode官网:www.qrcode.com
二维码的特点
  • 存储大容量信息
    传统条形码最多只能支持20位左右的信息,二维码则最多可以支持7089个数字,4296个字母,1817个汉字。


  • 小空间内打印


  • 有效表现各种字母
    QR码是日本国产的二维码,因此更适合处理日文字母和汉字。QR码字集规格定义是按照日本标准“JIS第一级和第二级的汉字”制定的,因此在日语处理方面,每一个全角字母和汉字都用13比特的数据处理,效率较高,与其他二维码相比,可以多存储20%以上的信息。


  • 抗破损能力强
    QR码具备“纠错功能”,即使部分编码变脏或破损,也可以恢复数据。数据恢复以码字为单位(是组成内部数据的单位,在QR码的情况下,每8比特代表1码字),最多可以纠错约30%(根据变脏和破损程度的不同,也存在无法恢复的情况)。


  • 任意方向识别
    QR码从360°任一方向均可快速读取。原因在于QR码中的3处定位图案,可以帮助QR码不受背景样式的影响,实现快速稳定的读取。


  • 支持数据合并功能
    QR码可以将数据分割为多个编码,最多支持16个QR码。使用这一功能,还可以在狭长区域内打印QR码。另外,也可以把多个分割编码合并为单个数据。

二维码的版本与纠错能力二维码版本
二维码一共有40个尺寸,官方叫版本Version。Version 1是21 x 21的矩阵,Version 2是 25 x 25的矩阵,Version 3是29的尺寸,每增加一个version,就会增加4的尺寸,公式是:(V-1)4 + 21(V是版本号) 最高Version 40,(40-1)4+21 = 177,所以最高是177 x 177 的正方形。
二维码纠错能力
QR码具有“纠错功能”。即使编码变脏或破损,也可自动恢复数据。这一“纠错能力”具备4个级别,用户可根据使用环境选择相应的级别。调高级别,纠错能力也相应提高,但由于数据量会随之增加,编码尺寸也也会变大。
用户应综合考虑使用环境、编码尺寸等因素后选择相应的级别。 在工厂等容易沾染赃物的环境下,可以选择级别Q或H,在不那么脏的环境下,且数据量较多的时候,也可以选择级别L。一般情况下用户大多选择级别M(15%)。
  • 纠错使用RS编码

RS编码,又称里所码,即Reed-solomon codes,是一种前向纠错的信道编码,对由校正过采样数据所产生的多项式有效。当接收器正确的收到足够的点后,它就可以恢复原来的多项式,即使接收到的多项式上有很多点被噪声干扰失真。
二维码尺寸选择
QR码的各个版本结合数据量、字符类型和纠错级别,均设有相对应的最多输入字符数。也就是说,如果增加数据量,则需要使用更多的码元来组成QR码,QR码就会变得更大。
例如,需要输入的数据为100位的数字时,通过以下步骤来选定。
1.假设要输入的数据种类为“数字” 。
2.从“L”、 “M”、 “Q”、 “H”中选择纠错级别。(假设选择“M”)
3.查看下表,先从数字列找出数字为100以上且接近100的,其次找出纠错级别“M”,两者交叉的部分就是最佳版本。
二维码的构成
  • 位置探测图形、位置探测图形分隔符、定位图形:

用于对二维码的定位,对每个QR码来说,位置都是固定存在的,只是大小规格会有所差异; 这三个定位图案有白边即位置探测图形分隔符,之所以三个而不是四个,因为三个就可以标识一个矩形了。
  • 校正图形

规格确定,校正图形的数量和位置也就确定了,Version 2以上(包括Version2)的二维码才需要这个。
  • 格式信息

表示该二维码的纠错级别,分为L、M、Q、H,存在于所有的尺寸中,用于存放一些格式化数据的。
  • 版本信息

即二维码的规格,QR码符号共有40种规格的矩阵(一般为黑白色),从21x21(版本1),到177x177(版本40),每一版本符号比前一版本 每边增加4个模块。在 >= Version 7以上,需要预留两块3 x 6的区域存放一些版本信息。
  • 数据和纠错码字

实际保存的二维码信息,和纠错码字(用于修正二维码损坏带来的错误)。
二维码的生成过程编码过程编码类型
QR码支持数字编码、字符编码、字节编码、日文编码、特殊字符编码、混合编码等。
  • 数字编码

从0到9。如果需要编码的数字的个数不是3的倍数,那么,最后剩下的1或2位数会被转成4或7bits,则其它的每3位数字会被编成 10,12,14bits,编成多长还要看二维码的尺寸。
  • 字符编码

包括 0-9,大写的A到Z(没有小写),以及符号$ % * + – . / : 包括空格。这些字符会映射成一个字符索引表。如下所示:(其中的SP是空格,Char是字符,Value是其索引值) 编码的过程是把字符两两分组,然后转成下表的45进制,然后转成11bits的二进制,如果最后有一个落单的,那就转成6bits的二进制。而编码模式和字符的个数需要根据不同的Version尺寸编成9, 11或13个二进制(如下表中Table 3)
字符编码示例:
  • 一、生成数据码

在Version 1的尺寸下,纠错级别为H的情况下,编码: AC-42
  • 从字符索引表中找到 AC-42 这五个字条的索引 (10,12,41,4,2)
  • 两两分组: (10,12) (41,4) (2)
  • 把每一组转成11bits的二进制:

(10,12) 10x45+12 等于 462 转成 00111001110
(41,4) 41x45+4 等于 1849 转成 11100111001
(2) 等于 2 转成 000010
  • 把这些二进制连接起来:00111001110 11100111001 000010
  • 把字符的个数转成二进制 (Version 1-H为9 bits ): 5个字符,5转成 000000101
  • 在头上加上编码标识 0010 和第5步的个数编码: 0010 000000101 00111001110 11100111001 000010
  • 添加结束符0000
  • 8bits重排,如果所有的编码加起来不是8个倍数我们还要在后面加上足够的0,比如上面一共有78个bits,所以,我们还要加上2个0,然后按8个bits分好组 00100000 00101001 11001110 11100111 00100001 00000000
  • 补齐码,最后,如果如果还没有达到我们最大的bits数的限制,我们还要加一些补齐码(Padding Bytes),Padding Bytes就是重复下面的两个bytes:11101100 00010001 关于每一个Version的每一种纠错级别的最大Bits限制,可以参看[QR Code Spec]的第28页到32页的Table-7一表。
    按照最低21*21H级别纠错规格72个bits,一共需要9组 还差三个,补齐后即可得到数据码:00100000 00101001 11001110 11100111 00100001 00000000 11101100 00010001 11101100
    上面的编码就是数据码了,叫Data Codewords,每一个8bits叫一个codeword,我们还要对这些数据码加上纠错信息。

  • 二、通过数据码生成纠错码

首先,我们需要对数据码进行分组,也就是分成不同的Block,然后对各个Block进行纠错编码,对于如何分组,我们可以查看[QR Code Spec]的第33页到44页的Table-13到Table-22的定义表。注意最后两列:
  • Number of Error Code Correction Blocks :需要分多少个块
  • Error Correction Code Per Blocks:每一个块中的code个数,所谓的code的个数,也就是有多少个8bits的字节。

例如:上述的Version 5 + Q纠错级:需要4个Blocks(2个Blocks为一组,共两组),头一组的两个Blocks中各15个bits数据 + 各 9个bits的纠错码(注:表中的codewords就是一个8bits的byte)
下图给一个5-Q的示例(因为二进制写起来会让表格太大,所以,我都用了十进制,我们可以看到每一块的纠错码有18个codewords,也就是18个8bits的二进制数)
注:二维码的纠错码主要是通过Reed-Solomon error correction(里德-所罗门纠错算法)来实现的。
  • 三、最终编码

二维码的混乱技术还没有玩完,它还要把数据码和纠错码的各个codewords交替放在一起。如何交替呢,规则如下:
对于数据码:把每个块的第一个codewords先拿出来按顺度排列好,然后再取第一块的第二个,如此类推。假如我们用HELLO WORLD的字符串的数据码:
00100000 01011011 00001011 01111000 11010001 01110010 11011100 01001101 01000011 01000000 11101100 00010001 11101100
Data Codewords如下:
块 1
67
85
70
134
87
38
85
194
119
50
6
18
6
103
38

块 224624666711813424273886221981991466
块 31822302471195071181348738826134151507
块 4702471188619461515016236172361723617236
先竖再横向:67, 246, 182, 70, 85,246,230 ,247 ……… ……… ,38,6,50,17,7,236
对于纠错码,也是一样:
块 1
213
199
11
45
115
247
241
223
229
248
154
117
154
111
86
161
111
39
块 28720496602021821241572001342712920917163163120133
块 314811617721276133752422387619523018910108240192141
块 423515951732414759331064025517282213132178236
和数据码取的一样,得到:213,87,148,235,199,204,116,159,…… …… 39,133,141,236
然后,再把这两组放在一起(纠错码放在数据码之后)得到:
67, 246, 182, 70, 85, 246, 230, 247, 70, 66, 247, 118, 134, 7, 119, 86, 87, 118, 50, 194, 38, 134, 7, 6, 85, 242, 118, 151, 194, 7, 134, 50, 119, 38, 87, 16, 50, 86, 38, 236, 6, 22, 82, 17, 18, 198, 6, 236, 6, 199, 134, 17, 103, 146, 151, 236, 38, 6, 50, 17, 7, 236, 213, 87, 148, 235, 199, 204, 116, 159, 11, 96, 177, 5, 45, 60, 212, 173, 115, 202, 76, 24, 247, 182, 133, 147, 241, 124, 75, 59, 223, 157, 242, 33, 229, 200, 238, 106, 248, 134, 76, 40, 154, 27, 195, 255, 117, 129, 230, 172, 154, 209, 189, 82, 111, 17, 10, 2, 86, 163, 108, 131, 161, 163, 240, 32, 111, 120, 192, 178, 39, 133, 141, 236
这就是我们的数据区。
绘制二维码
先看之前这个图
添加位置探测图形
首先,先把位置探测图形图案画在三个角上。(无论Version如何,这个图案的尺寸就是这么大7*7)
绘制校正图形( 5*5)

关于Alignment的位置,可以查看[QR Code Spec]的第81页的Table-E.1的定义表(下表是不完全表格)
下图是根据上述表格中的Version8的一个例子(6,24,42)
绘制定位图形
接下来是定位图形的线。
再接下来是格式信息,下图中的蓝色部分。
格式信息是一个15个bits的信息,每一个bit的位置如下图所示:(注意图中的Dark Module,会永远出现)
这15个bits中包括:
  • 5个数据bits:其中,2个bits用于表示使用什么样的Error Correction Level, 3个bits表示使用什么样的Mask
  • 10个纠错bits。主要通过BCH Code来计算

然后15个bits还要与101010000010010做XOR操作。这样就保证不会因为我们选用了00的纠错级别和000的Mask,从而造成全部为白色,这会增加我们的扫描器的图像识别的困难。
错误级别:
添加版本信息
(版本7以后需要这个编码),下图中的蓝色部分。
版本信息 一共是18个bits,其中包括6个bits的版本号以及12个bits的纠错码,下面是一个示例
而其填充位置如下图:
绘制数据和数据纠错码
然后是填接我们的最终编码,最终编码的填充方式如下:从左下角开始沿着红线填我们的各个bits,1是黑色,0是白色。如果遇到了上面的非数据区,则绕开或跳过。
转换为掩码图案
这样下来,我们的图就填好了,但是,也许那些点并不均衡,如果出现大面积的空白或黑块,会告诉我们扫描识别的困难。所以,我们还要做Masking操作,QR的Spec中说了,QR有8个Mask你可以使用,如下所示:其中,各个mask的公式在各个图下面。所谓mask,就是和上面生成的图做XOR操作。Mask只会和数据区进行XOR,不会影响功能区。(注:选择一个合适的Mask也是有算法的
其Mask的标识码如下所示:(其中的i,j分别对应于上图的x,y)
下面是Mask后的一些样子,我们可以看到被某些Mask XOR了的数据变得比较零散了。
Mask过后的二维码就成最终的图了。





回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|好好搭搭在线 ( © 好好搭搭在线 浙ICP备19030393号-1 )

GMT+8, 2024-3-29 21:09 , Processed in 0.345324 second(s), 25 queries .

Powered by Discuz!

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表