C++中生成二维码-libqrencode

news2024/9/28 17:29:54

文章目录

    • 前言
    • libqrencode
    • 在qt中调用libqrencode
    • 其他

前言

二维码的种类很多。本文仅介绍,如何用C++生成QR码(QRcode)。通常而言,我们不需要知道QR码的详细结构,如QrCode的结构原理与实战 | 张展鹏的博客。我们只需要,可以将文本转换成二维码,控制二维码的大小(分辨率),即可。所以,我推荐在这个站点里面逛逛:什么是QR码? | QRcode.com | DENSO WAVE。

建议读下上面链接中的这几个内容:

  • QR码的成功之路 | QRcode.com | DENSO WAVE

  • QR码的种类 | QRcode.com | DENSO WAVE

  • 关于纠错功能| QRcode.com | DENSO WAVE – 这个链接我们可以根据文本大小,选择合适版本的QR码,选择适合的纠错级别。

  • 如何导入?| QRcode.com | DENSO WAVE – 如果不仅仅是在较大的电子屏幕上现实,还需要打印出了,考虑分辨率,需要读下这个链接,选择合适的尺寸。

本文目前,仅简单使用GitHub - fukuchi/libqrencode: A fast and compact QR Code encoding library,生成二维码。

本文详细代码见仓库


libqrencode

本节目标:将一个字符串转换成一个png图片。

没有啥好的参考示例,所以我们从命令行入手。首先,在Linux下,安装qrencode的二进制文件和库。然后,通过命令将文本转换成图片。我们顺着命令的执行逻辑,看下命令的源码,即可了解大体操作。

# linux安装二进制和库
sudo apt install qrencode libqrencode

# 将文本转换成图片
qrencode --output=tmp.png --type=PNG "hello world"


# window中安装库(库中没有包含二进制,默认的编写选项没开吧)
vcpkg.exe install libqrencode

结合QRencode: Main Page,阅读qrencode(intext, length, outfile)处的代码,可以看到逻辑分为两步:将字符串转换成可以绘制QR二维的信息结构;将信息结构转换成图片。将信息结构转换成图片部分,本文不介绍(我也没去看png的api,我直接把qrencode生成png的代码抠出来运行的)。

下面我们来写demo,演示下。这里仅仅列出核心逻辑。转换成图片的writePNG函数代码没有列出,详细见仓库。

int main(int argc, char *argv[]) {
  std::string str("你好,世界");
  int version = 0;
  QRcode *qrcode =
      QRcode_encodeString(str.c_str(), version, QR_ECLEVEL_L, QR_MODE_8, 1);
  // QRcode *qrcode = QRcode_encodeData(
  //     str.size(), (const unsigned char *)str.c_str(), version, QR_ECLEVEL_L);

  if (qrcode == NULL) {
    if (errno == ERANGE) {
      fprintf(stderr,
              "Failed to encode the input data: Input data too large\n");
    } else {
      perror("Failed to encode the input data");
    }
    return -1;
  }

  if (qrcode->version != version) {
    std::cout << "the input data too large" << std::endl;
    std::cout << "change version from " << version << " to " << qrcode->version;
  }

  writePNG(qrcode, "tmp.png", PNG_TYPE);
  QRcode_free(qrcode);
  return 0;
}

下面简单介绍上上面的过程。

  • extern QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive); 将传入的字符串(不能包含null)转换成QRcode的信息。version是版本号,不同版本可以容纳不同的字符数量(详细见前言中的链接)。可以根据传入的字符数量,版本号,选择合适的纠错等级。如果要传入非字母数字的内容,使用QR_MODE_8,对字符串进行编码(不知道它咋编码的,可能是utf8吧)。

  • QRcode_encodeString编码失败,返回NULL, 错误记录在erron中。

  • 如果不严格限制版本。当传入的字符数量大于版本所能容纳的字符数量时,版本会自动调整。如果不是很在意版本,传入0即可,会根据传入的文本选择最小的版本。

在windows上编译代码需要注意下。如果没有添加-DCMAKE_BUILD_TYPE=Releasepkgconfig默认链接的是debug版本,见:release project using pkgconfig link with debug library · Issue #29762 · microsoft/vcpkg · GitHub

cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . --config Release

结果如下。

在这里插入图片描述


在qt中调用libqrencode

本节目标:点击按钮,将文本框中的字符串,转换成二维码在界面上显示。

不需要在生成图片了,而是直接在qt中绘制。QRcode Struct中的数据,最低位为1/0为黑色/白色。

参考:Qt + libqrencode 生成二维码_qt生成二维码_龚建波的博客-CSDN博客 、Qt生成二维码

没啥难度,照葫芦画瓢,抄抄改改就好。

QPixmap MainWindow::GernerateQRCode(const QString &text, int scale) {
  QPixmap ret;
  int version = 0;
  QRcode *qrcode = QRcode_encodeString(text.toStdString().c_str(), version,
                                       QR_ECLEVEL_L, QR_MODE_8, 1);
  if (qrcode == NULL) {
    qDebug() << "Failed to encode the input data, errno is: " << errno;
    return ret;
  }
  auto cleanup = qScopeGuard([qrcode] { QRcode_free(qrcode); });

  if (qrcode->version != version) {
    qDebug() << "the input data too large";
    qDebug() << "change version from " << version << " to " << qrcode->version;
  }

  int width = qrcode->width * scale;
  int heigh = qrcode->width * scale;
  QImage image(width, heigh, QImage::Format_Mono);
  QPainter painter(&image);
  painter.fillRect(0, 0, width, heigh, Qt::white); // 背景填充白色
  painter.setPen(Qt::NoPen); // 填充但是不需要边界线
  painter.setBrush(QBrush(Qt::black, Qt::SolidPattern)); // 设置画笔为黑色
  for (int y = 0; y < qrcode->width; ++y) {
    for (int x = 0; x < qrcode->width; ++x) {
      if (qrcode->data[y * qrcode->width + x] & 0x01) {
        painter.drawRect(x * scale, y * scale, scale, scale);
      }
    }
  }
  ret = QPixmap::fromImage(image);
  return ret;
}

void MainWindow::onButtonClicked() {
  ui->button_qrcode->setEnabled(false);

  int width = ui->lab_qrcode->width();
  int heigh = ui->lab_qrcode->height();
  QString text = ui->textEdit_qrcode->toPlainText();
  if (!text.isEmpty()) {
    QPixmap pixmap = GernerateQRCode(text, 10);
    pixmap = pixmap.scaled(width, heigh, Qt::IgnoreAspectRatio,
                           Qt::SmoothTransformation);
    ui->lab_qrcode->setPixmap(pixmap);
  }

  ui->button_qrcode->setEnabled(true);
}

结果如下。

在这里插入图片描述


其他

还有些其他库没有尝试:

  • How to draw a QR code with Qt in native C/C++ - Stack Overflow

  • GitHub - nayuki/QR-Code-generator: High-quality QR Code generator library in Java, TypeScript/JavaScript, Python, Rust, C++, C. – QR-Code-generator

  • QR Code Scanner using OpenCV 4 (C++ & Python) | LearnOpenCV – opencv

  • GitHub - danielsanfr/qt-qrcode: Qt/C++ library for encoding and visualization of data in a QR Code symbol – qt对libqrencode库的封装库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/711939.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python——— 字符串

&#xff08;一&#xff09;字符串 字符串是 Python 中最常用的数据类型。我们可以使用引号 ( 或 " ) 来创建字符串。顾名思义&#xff0c;羊肉串是由羊肉做成的串&#xff0c;而字符串就是由字符组成的。 字符串的本质是&#xff1a;字符序列。 2 Python 不支持单字符…

Kafka 小结

Kafka 是由 Linkedin 开发并开源的分布式消息系统&#xff0c;因其分布式及高吞吐率而被广泛使用&#xff0c;现已与 Cloudera Hadoop、Apache Storm、Apache Spark、Flink 集成。 Kafka 使用场景 页面访问量 PV、页面曝光 Expose、页面点击 Click 等行为事件&#xff1b;实时计…

低分辨率图像中目标检测(附论文下载)

关注并星标 从此不迷路 计算机视觉研究院 公众号ID&#xff5c;ComputerVisionGzq 学习群&#xff5c;扫码在主页获取加入方式 论文地址&#xff1a;https://arxiv.org/pdf/2201.02314.pdf 计算机视觉研究院专栏 作者&#xff1a;Edison_G 超分辨率&#xff08;SR&#xff09;等…

【Openvino03】深入了解OpenVINO™ 工具包与Jupyter Notebooks工程

接上一篇&#xff0c;本篇将以OpenVINO™ 工具包、Jupyter Notebook工具以及OpenVINO™ Notebooks工程为基础&#xff0c;依照构建环境、工具学习、案例学习、实战部署的顺序引导初学者完成从0到1学习人工智能的全过程&#xff0c;希望众多对人工智能感兴趣的开发者&#xff0c…

【多维BFS】ABC308 D

VP的时候居然花了半小时&#xff01; 可恶&#xff01; D - Snuke Maze (atcoder.jp) 题意&#xff1a; 思路&#xff1a; 首先&#xff0c;我们发现到达一个格子之后&#xff0c;下一个格子的字符是确定的 但是&#xff0c;下一个格子到底是哪个是不确定的 下一个格子不…

FreeRTOS源码解析——第一章 整体架构

FreeRTOS源码解析 第一章 FreeRTOS 整体架构 第二章 FreeRTOS 编程规范 第三章 FreeRTOS 内存管理 第四章 FreeRTOS 任务管理 第五章 FreeRTOS 消息队列 第六章 FreeRTOS 软件定时器 第七章 FreeRTOS 信号量 第八章 FreeRTOS 互斥量 第九章 FreeRTOS 任务通知 第十章 FreeRTOS…

算法习题之宏观分层问题

宏观分层 习题1 给定一个正方形矩阵matrix&#xff0c;原地调整成顺时针90度转动的样子习题2 给定一个长方形矩阵matrix&#xff0c;实现转圈打印习题3 给定一个正方形或者长方形矩阵matrix&#xff0c;实现zigzag打印习题4 输入N,在控制台上输出初始边长为N的图案 习题1 给定一…

U盘数据丢失是什么原因?轻松让U盘数据恢复的教程

在数字化时代&#xff0c;我们不可避免地使用各种便携式存储设备&#xff0c;如U盘&#xff0c;来传输和存储重要数据。然而&#xff0c;有时我们可能不小心删除了U盘中的文件&#xff0c;或者格式化了U盘等等而导致数据丢失。这种情况下&#xff0c;你可能会困惑地想知道&…

机器学习——基于Tensorflow和Keras实现卷积神经网络CNN——猫狗分类

文章目录 环境的配置神经网络CNN的介绍卷积前馈神经网络卷积神经网络应用邻域 数据集准备数据预处理构建基准模型 总结什么是过拟合&#xff08;overfit&#xff09;&#xff1f;什么是数据增强&#xff1f;单独制作数据增强&#xff0c;精确率提高了多少&#xff1f; 然后再添…

硬件大熊原创合集(2023/06更新)

06月份更新篇章&#xff1a; 一款射频芯片的layout设计指导案例-篇章1 一款射频芯片的layout设计指导案例-篇章2 警惕超声波工艺对晶振造成损伤 走嵌入式方向&#xff0c;一定要软硬件都懂吗&#xff1f; 6月份广州光亚展&#xff0c;和电子电力大咖文老师见了个面&#xff0c;…

2023车载摄像头9大热点趋势

摘要&#xff1a; 相较于消费类电子摄像头&#xff0c;车载摄像头的工作环境极度恶劣&#xff0c;比如说震动、高温、雨雾、低温、光线变化剧烈等。而车载摄像头以驾驶安全为目的&#xff0c;上述各个工作状态下&#xff0c;均需要能获取稳定、可靠、清晰的周边环境数据。 近年…

HOT36-二叉树的中序遍历

leetcode原题链接&#xff1a;二叉树的中序遍历 题目描述 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a…

BUUCTF藏藏藏

也是一个图片文件&#xff0c;和一个txt文件 txt文件中是一个提交flag格式&#xff0c;没啥用 拿去010打开后发现可能存在隐藏文件 这个格式说明还有解压文件吧&#xff0c;但是为啥分离不出来呢 刚好有另外一个分离文件的软件foremost 解压后打开在zip文件下有一个福利docx文件…

【零基础入门学习Python---Python网络编程保姆级教程】

&#x1f680; Python &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

GDB寻找segmentation fault位置

一、在当前文件夹下生成指定二进制文件的core文件 查看允许core文件空间大小&#xff1a; ulimit -c修改core文件空间为无限大&#xff1a; ulimit -c unlimited让core文件生成在当前目录下&#xff1a; sudo bash -c echo core.%e.%p > /proc/sys/kernel/core_pattern再…

2023黑马头条.微服务项目.跟学笔记(二)

2023黑马头条.微服务项目.跟学笔记 二 app端文章查看&#xff0c;静态化freemarker,分布式文件系统minIO今日简介学习内容1.文章列表加载1.1 需求分析1.2 表结构分析思考:表的垂直拆分 1.3 导入文章数据库1.3.1 导入数据库1.3.2 导入对应的实体类总结 1.4 实现思路1.4.1 sql练习…

hippo - 提升我们团队工程效率的工具

1. 背景 我们 shopeepay 团队是一个比较大的前端团队&#xff08;80成员&#xff09;&#xff0c;团队内部分布着 react native、javascript npm包、react component npm包、serverless、普通的react工程等多种类型的项目&#xff0c;每种项目类型中的每个项目都有它们自己的配…

Windows 使用Git使用Gitee仓库

1.本地创建文件夹。图中例子&#xff0c;我在桌面创建了文件夹。 2.打开 Git Bash Here. 3.Git Bash 的部分指令。 ls 查看当前文件夹 mkdir gittest01 创建文件夹 cd gittest01 进入文件夹 git init 创建本地仓库 git config --global user.name"chengqian" 创建者…

Redis主从复制模式的2

搭建完后可以去测试一下这几个问题: 1.主机中的数据会复制到从节点中 2.主机中新增的数据会同步到从节点中 3.redis集群后,从节点只能读(slave),主节点可以写(master) 4.主机重启后还是主节点 5.从机重启后也会变成主节点 血脉相传 一个主机master理论上可以有多个从机slave…

抖音短视频矩阵号系统开发者开源部署分享(一)

抖音是一款备受欢迎的短视频APP&#xff0c;拥有数亿的用户&#xff0c;其中包括了大量的粉丝。为了让更多的人能够发现和观看到你的视频&#xff0c;抖音SEO是必不可少的一环&#xff0c;特别是对于拥有企业或个人品牌的用户来说。在这个过程中&#xff0c;抖音SEO源码的开源部…