Qt+libqrencode+QZXing 二维码生成原理和识别
开发环境 Ubuntu18.04 + qt 5.9.3 +libqrencode + QZXing
先下载libqrencode,Git 地址:https://github.com/fukuchi/libqrencode
解压后,cmake 一下,然后make 编译。
编译成功,将静态库和头文件单独拷贝。
在项目pro中使用库。
#-------------------------------------------------
#
# Project created by QtCreator 2018-05-05T20:15:37
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Qrcode
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGSa
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp \
qrcode.cpp
HEADERS += \
mainwindow.h \
qrcode.h
FORMS += \
mainwindow.ui
unix:!macx: LIBS += -L$$PWD/../qrcode/ -lqrencode
INCLUDEPATH += $$PWD/../qrcode
DEPENDPATH += $$PWD/../qrcode
unix:!macx: PRE_TARGETDEPS += $$PWD/../qrcode/libqrencode.a
unix:!macx: LIBS += -L$$PWD/../QZXing/ -lQZXing
INCLUDEPATH += $$PWD/../QZXing
DEPENDPATH += $$PWD/../QZXing
QRcodeEncode 源码:
#ifndef QRCODE_H
#define QRCODE_H
#include "qrencode.h"
#include <QColor>
#include <QPainter>
class QRcodeEncode
{
public:
QRcodeEncode();
void setString(QString str);
int getQRWidth() const;
bool saveImage(QString name ,int size);
~QRcodeEncode();
void draw(QPainter &painter, int width, int height);
private:
QRcode* qr;
QString string;
};
#endif // QRCODE_H
#include "qrcode.h"
QRcodeEncode::QRcodeEncode()
{
qr = new QRcode();
}
int QRcodeEncode::getQRWidth() const
{
if(qr != NULL)
{
return qr->width;
}
else
{
return 0;
}
}
QRcodeEncode::~QRcodeEncode()
{
if(qr != NULL)
{
QRcode_free(qr);
}
}
void QRcodeEncode::setString(QString str)
{
string = str;
if(qr != NULL)
{
QRcode_free(qr);
}
qr = QRcode_encodeString(string.toStdString().c_str(),1,QR_ECLEVEL_L,QR_MODE_8,1);
}
bool QRcodeEncode::saveImage(QString fileName, int size)
{
if(size != 0 && !fileName.isEmpty())
{
QImage image(size, size, QImage::Format_Mono);
QPainter painter(&image);
QColor background(Qt::white);
painter.setBrush(background);
painter.setPen(Qt::NoPen);
painter.drawRect(0, 0, size, size);
if(qr != NULL)
{
draw(painter, size, size);
}
return image.save(fileName);
}
else
{
return false;
}
}
void QRcodeEncode::draw(QPainter &painter, int width, int height)
{
QColor foreground(Qt::black);
painter.setBrush(foreground);
const int qr_width = qr->width > 0 ? qr->width : 1;
double scale_x = width / qr_width;
double scale_y = height / qr_width;
for( int y = 0; y < qr_width; y ++)
{
for(int x = 0; x < qr_width; x++)
{
unsigned char b = qr->data[y * qr_width + x];
if(b & 0x01)
{
QRectF r(x * scale_x, y * scale_y, scale_x, scale_y);
painter.drawRects(&r, 1);
}
}
}
}
下载解码库 QZXing,https://github.com/ftylitak/qzxing/
解压后用Qt编译source中的源码。
编译完成后将库和头文件单独拷贝:
libQZXing.so libQZXing.so.2.3 QZXing_global.h
libQZXing.so.2 libQZXing.so.2.3.0 qzxing.h
在项目中使用库。
窗体源码。
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "qrcode.h"
#include <QPainter>
#include "qzxing.h"
#include <QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
protected:
void paintEvent(QPaintEvent*);
QSize sizeHint() const;
QSize minimumSizeHint() const;
private:
QString string;
QRcodeEncode *m_qrcode;
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_qrcode = new QRcodeEncode();
m_qrcode->setString("Hello QR Code");
QImage img;//解码很简单
img.load("/home/rui/Code/build-Qrcode-Desktop_Qt_5_9_3_GCC_64bit-Debug/Qrcode.png");
QZXing qzxing;
qDebug()<<qzxing.decodeImage(img);
}
MainWindow::~MainWindow()
{
delete ui;
}
QSize MainWindow::sizeHint() const
{
QSize s;
if(m_qrcode != NULL)
{
int qr_width = m_qrcode->getQRWidth() > 0 ? m_qrcode->getQRWidth() : 1;
s = QSize(qr_width*4,qr_width*4);
}
else
{
s = QSize(50,50);
}
return s;
}
QSize MainWindow::minimumSizeHint() const
{
QSize s;
if(m_qrcode != NULL)
{
int qr_width = m_qrcode->getQRWidth() > 0 ? m_qrcode->getQRWidth() : 1;
s = QSize(qr_width,qr_width);
}
else
{
s = QSize(50, 50);
}
return s;
}
void MainWindow::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QColor background(Qt::white);
painter.setBrush(background);
painter.setPen(Qt::NoPen);
painter.drawRect(0, 0, width(), height());
if(m_qrcode != NULL)
{
m_qrcode->draw(painter, width(), height());
}
}
生成和解码:
智能推荐
二维码的扫描和生成二维码
前言 之前自己一直想要去实现一个二维码的扫描和生成,但是一直拖到现在,今天趁着夜色落幕,气氛还算可以(各种声音的夹杂中),完成了这个扫描和生成二维码的工具,在这里总结一下。 首先普及一下什么是二维码和二维码开源库 QR Code QRCode简介: QRCode全称Quick Response Code 通过在一个矩形区域内使用黑白像素来进行编码 高纠错性、高可用性、高识别...
vue生成二维码和二维码中带图片
一、生成简单的二维码(不带图片) 1.引入插件 2.页面中使用 页面中引入 二、中间带有图片的二维码 1.引入插件 2.页面使用 拿走,不用谢!!!送人玫瑰,手留余香...
Android 二维码 生成和识别(附Demo源码)
今天讲一下目前移动领域很常用的技术——二维码。现在大街小巷、各大网站都有二维码的踪迹,不管是IOS、Android、WP都有相关支持的软件。之前我就想了解二维码是如何工作,最近因为工作需要使用相关技术,所以做了初步了解。今天主要是讲解如何使用ZXing库,生成和识别二维码。这篇文章实用性为主,理论性不会讲解太多,有兴趣可以自己查看源码。 1、ZXing库介绍 这里简...
利用Zxing生成和识别二维码(java版本)
Zxing是Google开发的用来生成和识别二维码的库,可以帮助我们快速方便的生成和识别出二维码. 1.使用Zxing我们首先应该导入它的依赖 2.二维码的生成与识别(带logo二维码和不带logo二维码) QrUtil.java 3.单元测试类 QrApplicationTests.java 4.补充 Zxing文档:https://zxing.github.io/zxing/apidocs/ ...
OSI七层模型与TCP/IP四层模型
一、OSI七层模型 开放系统互连参考模型 (Open System Interconnect 简称OSI)是国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)联合制定的开放系统互连参考模型,为开放式互连信息系统提供了一种功能结构的框架。 它从低到高分别是:物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。 1、物理层 物理层并不是物理媒体本身,它只是开放系统中利用物理媒体实现...
猜你喜欢
Postman 上传文件
环境 Postman macbook pro 前言 在做导入导出时,导出好办,直接使用浏览器就可以了, 但是导入,如果我想本地测试就麻烦了, 一开始我是叫一个前端同事,帮忙写了一个页面。 但是他写的这个页面,需要nodejs支持,也就是需要先启动一个服务,端口好像是5000,时间长了,我就忘了怎么启动,毕竟是前端的东西。 今天再次研究下postman如何上传文件,本地调试,终于被我整出来了。 错误...
树莓派Linux基础(一):查看文件系统
前言 给树莓派开启了SSH服务后,你可以在局域网内通过终端查看文件系统,用命令行实现目录的变更和文件在系统中的移动。 主要命令 cd命令 浏览树莓派文件系统的用的最多的命令就是cd(change directory)字面意思就是更换目录。在cd之后要指明要变更的目标文件夹,可以是结对路径也可以是相对于当前目录的相对路径。 pwd命令 在任何目录下,即可以使用pwd(print working di...
Ubuntu 18.04 LTS安装NVIDIA显卡驱动
写在前面 换成Ubuntu系统后,系统默认安装的是X org提供的开源驱动nouveau,这个驱动可以胜任2D图形加速任务,但对3D图形处理就无能为力了。因此,在启动VMWare虚拟机的时候就经常报形如 “No 3D support is aviable from host”, "Hardware graphics acceleration is not avil...
前端测试二
前端测试二 1.css盒子模型由里到外由哪几部分组成?标准盒子模型与IE盒子模型设置的宽高有什么区别?可以通过什么方式转变? 2.分别使用 flex 布局和 grid 布局,水平垂直居中一张图片 3.响应式布局与自适应布局的区别 4.多个 inline 元素之间会有空隙,为什么?如何解决? 5.以480px,800px,1400px作为分隔点,用媒体查询如何书写?写出css框架即可。 6.单位 r...
Android中文件选择器的实现
转载请注明出处:http://blog.csdn.net/qinjuning 今天给大家分享下文件选择器的作用 , 具体就是获取用户在在SD卡选中的文件/文件夹路径 ,类似于C#中 OpenFileDialog控件(对C#的一站式开发还是念念不忘)。功能实现起来比较简单,主要是帮助大家节省开发时间。 网上流传较广的一个成品如下 <[Android实例]文件选择器>, 本文也是根据上面的...