0.前言
之前使用 libgrencode 生成二维码,LGPL 协议实在不方便,所以需要找一个 github 星星多的,代码简单最好 header-only,协议最好是 MIT 或者兼容协议而不是 GPL 或者 LPGL。
QR-Code-generator 正好符合这个要求,而且还提供 C / C++ / Java / Python / JS / Rust 等 6 种语言实现,直接把 qrcodegen.hpp / cpp 类文件放到我们项目里就能使用。
库链接:https://github.com/nayuki/QR-Code-generator
库官网:https://www.nayuki.io/page/qr-code-generator-library
1.基本使用
测试代码链接:https://github.com/gongjianbo/MyTestCode/tree/master/Qt/TestQt_20230711_QRCodeGen
效果展示:
测试代码:
void MainWindow::generate()
{
// 使用utf8编码
QByteArray str = ui->lineEdit->text().toUtf8();
const char *text = str.constData();
// 二维码有四个纠错等级,从低到高:L-%7/M-%15/Q-%25/H-%30
const qrcodegen::QrCode::Ecc level = qrcodegen::QrCode::Ecc::MEDIUM;
// 生成二维码
try
{
// 使用简易接口,默认 Version 范围 min=1, max=40
// const qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(text, level);
// 也可以指定符号版本,越大可容纳的信息越多,如果内容超出容量范围会抛异常
// 根据规范,Version1 是 21x21,Version2 是 25x25,每增加一个Version,就比前一版本每边增加 4 个模块
std::vector<qrcodegen::QrSegment> segs = qrcodegen::QrSegment::makeSegments(text);
const qrcodegen::QrCode qr = qrcodegen::QrCode::encodeSegments(segs, level, 1, 40);
const int size = qr.getSize();
// 填充位图
QImage image = QImage(size, size, QImage::Format_Grayscale8);
for (int row = 0; row < size; ++row)
{
uchar *line_ptr = image.scanLine(row);
for (int col = 0; col < size; ++col)
{
line_ptr[col] = (uchar)(qr.getModule(row, col) ? 0x00 : 0xFF);
}
}
// 放大一点看得更清楚
image = image.scaled(image.width() * 5, image.height() * 5);
// 生成后可以用手机扫一扫识别文字内容,注意内容为空可能扫不出来
ui->label->setPixmap(QPixmap::fromImage(image));
}
catch(std::invalid_argument e)
{
// 参数异常,如 minVersion > maxVersion
qDebug() << "catch invalid_argument" << e.what();
}
catch(qrcodegen::data_too_long e)
{
// 内容太长
qDebug() << "catch data_too_long" << e.what();
}
}