文章目录
(一)关于QR二维码
一:什么是二维码
二维码 (2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上) 分布的黑白相间的图形记录数据符号信息的。 在许多种类的二维条码中,常用的码制有:Data Matrix, Maxi Code, Aztec, QR Code, Vericode, PDF417, Ultracode, Code 49, Code 16K等。
1.堆叠式/行排式二维条码,如,Code 16K、Code 49、PDF417
2.矩阵式二维码,最流行莫过于QR CODE 二维码的名称是相对与一维码来说的,比如以前的条形码就是一个“一维码”,它的优点有:二维码存储的数据量更大;可以包含数字、字符,及中文文本等混合内容;有一定的容错性(在部分损坏以后可以正常读取);空间利用率高等。
二:什么是QR二维码
QR(Quick-Response) code是被广泛使用的一种二维码,解码速度快。 由DENSO(日本电装)公司开发,由JIS和ISO将其标准化。
QR码呈正方形,只有黑白两色。在3个角落,印有较小,像「回」字的的正方图案。这三个是帮助解码软件定位的图案,使用者不需要对准,无论以任何角度拍摄,内容仍可正确被读取。
三:将数据编码成QR码的流程
数据分析:确定编码的字符类型,按相应的字符集转换成符号字符; 选择纠错等级,在规格一定的条件下,纠错等级越高其真实数据的容量越小。
数据编码:将数据字符转换为位流,每8位一个码字,整体构成一个数据的码字序列。其实知道这个数据码字序列就知道了二维码的数据内容。
数据可以按照一种模式进行编码,以便进行更高效的解码,例如:对数据:01234567编码(版本1-H), 1)分组:012 345 67 2)转成二进制:012→0000001100 345→0101011001 67 →1000011 3)转成序列:0000001100 0101011001 1000011 4)字符数 转成二进制:8→0000001000 5)加入模式指示符(上图数字)0001:0001 0000001000 0000001100 0101011001 1000011 对于字母、中文、日文等只是分组的方式、模式等内容有所区别。基本方法是一致的
纠错编码:按需要将上面的码字序列分块,并根据纠错等级和分块的码字,产生纠错码字,并把纠错码字加入到数据码字序列后面,成为一个新的序列。
在二维码规格和纠错等级确定的情况下,其实它所能容纳的码字总数和纠错码字数也就确定了,比如:版本10,纠错等级时H时,总共能容纳346个码字,其中224个纠错码字。 就是说二维码区域中大约1/3的码字时冗余的。对于这224个纠错码字,它能够纠正112个替代错误(如黑白颠倒)或者224个据读错误(无法读到或者无法译码), 这样纠错容量为:112/346=32.4%
构造最终数据信息:在规格确定的条件下,将上面产生的序列按次序放如分块中 按规定把数据分块,然后对每一块进行计算,得出相应的纠错码字区块,把纠错码字区块 按顺序构成一个序列,添加到原先的数据码字序列后面。 如:D1, D12, D23, D35, D2, D13, D24, D36, … D11, D22, D33, D45, D34, D46, E1, E23,E45, E67, E2, E24, E46, E68,…
构造矩阵:将探测图形、分隔符、定位图形、校正图形和码字模块放入矩阵中。
把上面的完整序列填充到相应规格的二维码矩阵的区域中
掩摸:将掩摸图形用于符号的编码区域,使得二维码图形中的深色和浅色(黑色和白色)区域能够比率最优的分布。 一个算法,不研究了,有兴趣的同学可以继续。
格式和版本信息:生成格式和版本信息放入相应区域内。 版本7-40都包含了版本信息,没有版本信息的全为0。二维码上两个位置包含了版本信息,它们是冗余的。 版本信息共18位,6X3的矩阵,其中6位时数据为,如版本号8,数据位的信息时 001000,后面的12位是纠错位。
(二)编译QRencode
libqrencode 可以使用cmake 进行编译
Linux:
cmake ..
make
Windows:
cmake .. -G "MinGW Makefiles"
mingw32-make.exe
(三)使用libqrencode.a
/*
* @Descripttion: 二维码编码
* @version: V 1.0
* @Author: Yueyang
* @email: 1700695611@qq.com
* @Date: 2020-11-26 11:43:15
* @LastEditors: Yueyang
* @LastEditTime: 2020-11-26 18:01:26
*/
#include <string.h>
#include "qrencode.h"
#include "cv.h"
#include "li_image.h"
#include "li_qrcode.h"
/**
* @name: Li_QREncode
* @msg: 二维码生成
* @param {BYTE* src字符串}
* @return {Li_Image*}
*/
Li_Image* Li_QREncode(BYTE* src)
{
QRcode* pQRC;
int unWidth, unWidthAdjusted, unDataBytes;
Li_Image* out;
BYTE* pSourceData,*pDestData,*pRGBData ;
if (pQRC = QRcode_encodeString(src, 0, QR_ECLEVEL_H, QR_MODE_8, 1))
{
unWidth=pQRC->width;
unWidthAdjusted = unWidth * 8 * 3;
if (unWidthAdjusted % 4)
unWidthAdjusted = (unWidthAdjusted / 4 + 1) * 4;
unDataBytes = unWidthAdjusted * unWidth * 8;
out=Li_Create_Image(8*unWidth,8*unWidth,LI_DEP_24U,LI_BMP_888);
pSourceData = pQRC->data;
pRGBData=out->data;
pSourceData = pQRC->data;
for (int y = 0; y < unWidth; y++)
{
pDestData = pRGBData + unWidthAdjusted * y * 8;
for (int x = 0; x < unWidth; x++)
{
if (*pSourceData & 1)
{
for (int l = 0; l < 8; l++)
{
for (int n = 0; n < 8; n++)
{
//以下三行是设置三基色,三基色都设置为0x00,则生成的二维码图片就是黑色的了,要什么颜色自己调整
*(pDestData + n * 3 + unWidthAdjusted * l) = 0x00;
*(pDestData + 1 + n * 3 + unWidthAdjusted * l) = 0x00;
*(pDestData + 2 + n * 3 + unWidthAdjusted * l) = 0x00;
}
}
}
pDestData += 3 * 8;
pSourceData++;
}
}
}
return out;
}
/*
* @Descripttion:
* @version:
* @Author: Yueyang
* @email: 1700695611@qq.com
* @Date: 2020-11-26 12:23:49
* @LastEditors: Yueyang
* @LastEditTime: 2020-11-26 15:04:58
*/
#include "cv.h"
#include "li_image.h"
#include "li_qrcode.h"
int main()
{
Li_Image* Qr=Li_QREncode("123.57.93.3");
Li_Save_Image("QR.bmp",Qr);
LILOG("OVER");
}
(四)效果
(五)写在后面
代码中有错误的地方还望指出。我已经将项目同步到了github,我会实时更新这个代码仓库。
项目github地址:
LiteCV