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

生成和解码:


版权声明:本文为lichangrui2009原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lichangrui2009/article/details/80215828

智能推荐

二维码的扫描和生成二维码

前言 之前自己一直想要去实现一个二维码的扫描和生成,但是一直拖到现在,今天趁着夜色落幕,气氛还算可以(各种声音的夹杂中),完成了这个扫描和生成二维码的工具,在这里总结一下。  首先普及一下什么是二维码和二维码开源库 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实例]文件选择器>, 本文也是根据上面的...