米尔电子
直播中

筑梦者与梦同行

8年用户 172经验值
擅长:嵌入式技术
私信 关注
[技术]

【米尔MYD-JX8MMA7开发板-ARM+FPGA架构试用体验】 十、QT二维码生成器

【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)数据区域(绿色圈),二维码的有效数据是存储在绿色区域里,这里不仅存储了有效数据,还有纠错码字,这样的话,就算二维码损坏部分都可以识别。
图片22.png图片23.png

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工程
图片24.png图片25.png

点击下一步直至完成

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 把刚刚解压的库文件添加进去
图片26.png

取消勾选已有的 main.cpp 、mainwindows.cpp 、mainwindows.h 然后 点击OK即可
图片27.png

添加后的工程目录变成了这样
图片28.png

运行之后发现没有错误(如果你不小心在上一步直接点了OK、工程会报错,原因是重复添加了之前的文件 右击打开pro文件 删除重复的 main.cpp 、mainwindows.cpp 、mainwindows.h 即可)
图片29.png

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按钮
图片30.png

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());

}
图片31.png

最后的效果

至此,我们的二维码生成器就做好了。

三、Ubuntu环境下编译

1.WindowsQt程序
图片32.png

左边红框便是QR Code编码的库文件,右边红框及生成的软件界面。

将其全部代码打成压缩包上传至Ubuntu系统。。

2.UbuntuQt程序界面
图片33.png

UbuntuQt界面没有显示QR Code编码的库,但是也是加载了。
图片34.png

工程的编译环境需要配置一下了,这样就可以直接编译出IMX8MMA7开发板所需的软件。
图片35.png

如图所示编译完成。

3.IMX8MMA7Qt运行界面

1)上传文件

将Ubuntu系统下编译好的文件复制到IMX8MMA7开发板当中。
图片36.png

2)运行软件
图片37.png

其中红色框,查看文件夹内容

其中黄色框,提示没有权限运行,并使用命令行授权

其中蓝色框,运行软件状态

3)实际效果
图片38.png

参考文献:

https://github.com/ftylitak/qzxing

回帖(1)

覃生

2023-5-23 10:14:29
{:20:}{:20:}{:20:}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分