Qt+libqrencode+QZXing 二维码生成原理和识别

本文介绍如何在Ubuntu环境下利用Qt结合libqrencode和QZXing库实现二维码的生成和解码。从库的安装配置到具体代码实现,详细说明了整个过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开发环境 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());
    }
}

生成和解码:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值