【MYD-JX8MMA7】 十一、QT绘制二维码
本文内容并非原创,整合了多个网络资源进行过程整理,详细的描述了QT绘制二维码的理论和实践。
QR Code编码方式使用非常普遍,早在15年我个人就使用过其开发过Android 版的二维码扫描APP软件,目前微信、支付宝、华为等等都支持此编码方式的二维码扫描。
一、二维码基本理论整理
1、简介
二维码又称二维条码,常见的二维码为QR Code,QR全称Quick Response,是一种编码方式。它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型。
国外对二维码技术的研究始于20世纪80年代末,在二维码符号表示技术研究方面已研制出多种码制,常见的有PDF417、QR Code、Code 49、Code 16K、Code One等。
中国对二维码技术的研究开始于1993年。中国物品编码中心对几种常用的二维码PDF417、QRCCode、Data Matrix、Maxi Code、Code 49、Code 16K、Code One的技术规范进行了翻译和跟踪研究。
2、二维码构成
以QR Code为例,也就是我们最常见的二维码,参照上面那个cxd1301的二维码。里面存储的信息其实是分割成多个部分的。
(1)探测区(红色圈),就是三个回字型正方形框。用来定位二维码边界。为啥是三个回字型,不是两个,不是4个?两个不足以定位,已知两个顶点,至少可以向上或向下画出两个不同正方形。4个顶点可以确定唯一正方形,但没办法做图形旋转角度矫正了,没法确定左上角、右下角,因为四个顶点全对称了。三个刚好,既能确定出唯一位置,又能任何角度拍照都可以旋转恢复成只有右下角没有探测区的0旋转标准图。
(2)定位线(蓝色框),用来做分割不同区域,方便定位,定位线始终是黑白相间的,且只有一行、一列,非常明显。
(3)版本信息(红色框),版本信息存的是这个二维码是什么版本,不同版本二维码大小不一样,比如版本1,是2121的正方形,版本2,是2525的正方形,最大版本是版本40,是177*177的正方形,显然版本越大,能存的信息就越多。
(4)格式信息(黄色圈),格式信息里存储了这个二维码数据是按什么模式解析。比如数字是0001,字母数字是0010,汉字是1101。cxd1301是字母数字,所以格式信息是0010。
(5)数据区域(绿色圈),二维码的有效数据是存储在绿色区域里,这里不仅存储了有效数据,还有纠错码字,这样的话,就算二维码损坏部分都可以识别。
3、二维码最大容量
二维码自身信息量越多,所需的像素点越多;像素越多,越难分辨和解码,因为扫码设备(摄像头)有分辨上限。800万(8M)像素的摄像头无法扫出16M像素(40964096)的二维码。即使4M二维码也难。所以目前可用的二维码都不会太大,比如某二维码生成网站最大只提供800800(约0.6M)的二维码生成服务。(注意这里的M是指像素点数量,不是图片的文件大小)解决大信息量生成二维码的办法之一是生成“高端”二维码——活码,『通过短网址指向保存在云端的信息』(via网络)。也就是说,活码本身的信息量只是一个短网址,它指向的网页(云端)信息量可以无限多,然而活码自身信息量不多,容易识别。
另外,云端内容即使更改,相应的活码(短网址)也可以保持不变。相当于『信息变了,码不变』。而如果用二维码直接存储,改一个字节就得换一个二维码了。你可以这样理解活码:用二维码存一部电影不现实,但存种子/链接是绰绰有余的。
目前综合查询的二维码容量如下
格式 容量
数字 最多7089字符
字母 最多4296字符
二进制数(8 bit) 最多2953字节
日文汉字/片假名 最多1817字符(采用Shift JIS)
中文汉字 最多984字符(采用UTF-8)
中文汉字 最多1800字符(采用BIG5)
二、二维码绘制源码
1、源码下载
Github上的大佬 Nayuki:https://github.com/nayuki 提供了QR Code码相关的图片生成库,包含了C、C++、Java、JavaScript 、Python 、Rust 等语言的各个版本,代码简洁清晰,质量非常高。
Github主页上获取本次实现相关的源代码 https://github.com/gengyuchao/QR-Code-generator
本次使用的是c++版本的代码 文件夹名为cpp
2、创建工程
1)Windows下创建QT工程
点击下一步直至完成
2)添加库源文件
将下载的 QR-Code-generator-master.zip 中的 cpp文件夹里的
“BitBuffer.cpp”、“BitBuffer.hpp”、
“QrCode.cpp”、“QrCode.hpp”、
“QrSegment.cpp”、“QrSegment.hpp”、
解压到工程目录“G:\Qt_Project\Create_QRcode”下
最一开始的工程目录是这样子的,然后我们在工程文件夹上右击,选择Add Existing Directory 把刚刚解压的库文件添加进去
取消勾选已有的 main.cpp 、mainwindows.cpp 、mainwindows.h 然后 点击OK即可
添加后的工程目录变成了这样
运行之后发现没有错误(如果你不小心在上一步直接点了OK、工程会报错,原因是重复添加了之前的文件 右击打开pro文件 删除重复的 main.cpp 、mainwindows.cpp 、mainwindows.h 即可)
3)编写二维码绘制函数
根据库的说明文档,我们可以知道这个库的使用方法如下:
C++ language:
#include
#include
#include "QrCode.hpp"
using namespace qrcodegen;
// Simple operation
QrCode qr0 = QrCode::encodeText("Hello, world!", QrCode::Ecc::MEDIUM);
std::string svg = qr0.toSvgString(4);
// Manual operation
std::vector segs =
QrSegment::makeSegments("3141592653589793238462643383");
QrCode qr1 = QrCode::encodeSegments(
segs, QrCode::Ecc::HIGH, 5, 5, 2, false);
for (int y = 0; y < qr1.getSize(); y++) {
for (int x = 0; x < qr1.getSize(); x++) {
(... paint qr1.getModule(x, y) ...)
}
}
添加头文件#include #include #include "QrCode.hpp" 使用命名空间
using namespace qrcodegen;
然后就可以使用下面的函数了
于是我创建了函数 void Show_QRcode_Picture() 并把它添加进 mainwindows.h头文件中
void MainWindow::Show_QRcode_Picture()
{
// Manual operation
std::vector segs =
QrSegment::makeSegments("3141592653589793238462643383");
QrCode qr1 = QrCode::encodeSegments(
segs, QrCode::Ecc::HIGH, 5, 5, 2, false);
for (int y = 0; y < qr1.getSize(); y++) {
for (int x = 0; x < qr1.getSize(); x++) {
//(... paint qr1.getModule(x, y) ...)
}
}
}
将实例代码添加进去
使用Qt的QImage进行图像的编辑 ->转换为QPixmap-> 在QLabel中显示
4)在mainwindows.ui中添加控件
添加QLabel、QTextEdit和一个Button按钮
5)代码实现
//添加头文件:
#include "QImage"
//创建二维码画布
QImage QrCode_Image=QImage(qr1.getSize(),qr1.getSize(),QImage::Format_RGB888);
//图像大小转换为适当的大小
QrCode_Image=QrCode_Image.scaled(ui->label->width(),ui->label->height(),
Qt::KeepAspectRatio);
//转换为QPixmap在Label中显示
ui->label->setPixmap(QPixmap::fromImage(QrCode_Image));
完整代码如下:
void MainWindow::Show_QRcode_Picture(QString message)
{
// Manual operation
std::vector<QrSegment> segs =
QrSegment::makeSegments(message.toLatin1());
QrCode qr1 = QrCode::encodeSegments(
segs, QrCode::Ecc::HIGH, 5, 5, 2, false);
//创建二维码画布
QImage QrCode_Image=QImage(qr1.getSize(),qr1.getSize(),QImage::Format_RGB888);
for (int y = 0; y < qr1.getSize(); y++) {
for (int x = 0; x < qr1.getSize(); x++) {
if(qr1.getModule(x, y)==0)
QrCode_Image.setPixel(x,y,qRgb(255,255,255));
else
QrCode_Image.setPixel(x,y,qRgb(0,0,0));
}
}
//图像大小转换为适当的大小
QrCode_Image=QrCode_Image.scaled(ui->label->width(),ui->label->height(),
Qt::KeepAspectRatio);
//转换为QPixmap在Label中显示
ui->label->setPixmap(QPixmap::fromImage(QrCode_Image));
}
void MainWindow::on_Create_Button_clicked()
{
Show_QRcode_Picture(ui->textEdit->toPlainText());
}
最后的效果
至此,我们的二维码生成器就做好了。
三、Ubuntu环境下编译
1.WindowsQt程序
左边红框便是QR Code编码的库文件,右边红框及生成的软件界面。
将其全部代码打成压缩包上传至Ubuntu系统。。
2.UbuntuQt程序界面
UbuntuQt界面没有显示QR Code编码的库,但是也是加载了。
工程的编译环境需要配置一下了,这样就可以直接编译出IMX8MMA7开发板所需的软件。
如图所示编译完成。
3.IMX8MMA7Qt运行界面
1)上传文件
将Ubuntu系统下编译好的文件复制到IMX8MMA7开发板当中。
2)运行软件
其中红色框,查看文件夹内容
其中黄色框,提示没有权限运行,并使用命令行授权
其中蓝色框,运行软件状态
3)实际效果
参考文献:
https://github.com/ftylitak/qzxing
更多回帖