QT二維碼生成和解析&Demo

目錄

一、前言

二、相關知識

三、效果展示

四、主要源碼簡析

五、源碼Demo


一、前言

本文主要介紹二維碼生成和解析的相關知識和例程

 

二、相關知識

①二維碼生成:

主要用到的是開源的二維碼QR碼編碼庫qrencode,需要使用到的庫文件爲下面的:

庫裏最重要的是下面的二維碼生成函數:

/*
string是生成二維碼的字符串;
2表示二維碼的版本,一般選1或2都可以;
QR_ECLEVEL_L表示容錯級別,容錯級別越高,相同的字符串生成的二維碼就越複雜,相對應的識別二維碼攝像頭也就需求精度越高;
QR_MODE_8表示生成二維碼數據的類型,一般選QR_MODE_8;
最後一個涉及到庫生成二維碼的一些判斷,選0即可。
返回值是生成二維碼的全部信息
*/
qr = QRcode_encodeString(string,2,QR_ECLEVEL_L,QR_MODE_8,0);

根據上面的函數可獲得生成二維碼的信息,還需將二維碼的結構體信息,轉換成圖片,用QPainter處理即可。qr->data包含了二維碼圖像的信息,其中每個數據的bit0位代表了點的顏色,1表示黑色,0表示白色。畫圖時先將畫布背景色設置爲白色,然後將爲1的點畫成黑色,爲0的點不畫。

②二維碼/條形碼解析

主要用到的是QZXing,網上有很多現成的,我的Demo也提供,主要的二維碼/條形碼解析過程:

QZXing decoder;
//解析類型:CODE128條形碼和二維碼,可自選
decoder.setDecoder( QZXing::DecoderFormat_CODE_128 | QZXing::DecoderFormat_QR_CODE);
QString result = decoder.decodeImage(img);

 

三、效果展示

①二維碼生成

②二維碼/條形碼解析

   

 

四、主要源碼簡析

①二維碼生成

qrcodegenerate.h

#ifndef QRCODEGENERATE_H
#define QRCODEGENERATE_H

#include <QWidget>
#include "./qrencode/qrencode.h"
#include <QPainter>

namespace Ui {
class QrcodeGenerate;
}

class QrcodeGenerate : public QWidget
{
    Q_OBJECT

public:
    explicit QrcodeGenerate(QWidget *parent = 0);
    ~QrcodeGenerate();
    void generateString(const QString &str);
    bool saveImage(const QString &fileName, int size=250);

protected:
    void paintEvent(QPaintEvent *);
    QSize sizeHint() const;
    QSize minimumSizeHint() const;

private:
    Ui::QrcodeGenerate *ui;
    void draw(QPainter &painter, int width, int height);
    QRcode *qr;

};

#endif // QRCODEGENERATE_H

 qrcodegenerate.cpp

#include "qrcodegenerate.h"
#include "ui_qrcodegenerate.h"

QrcodeGenerate::QrcodeGenerate(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::QrcodeGenerate)
{
    ui->setupUi(this);
    qr = NULL;
}

QrcodeGenerate::~QrcodeGenerate()
{
    if(qr != NULL)
    {
       QRcode_free(qr);
       qr = NULL;
    }
    delete ui;
}
bool QrcodeGenerate::saveImage(const 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 QrcodeGenerate::generateString(const QString& str)
{
    if(qr != NULL)
    {
        QRcode_free(qr);
    }
    //2:生成二維碼版本,建議選1或2;QR_ECLEVEL_L:容錯級別;QR_MODE_8:生成data數據的類型
    qr = QRcode_encodeString(str.toStdString().c_str(),
                             2,
                             QR_ECLEVEL_L,
                             QR_MODE_8,
                             0);
    update();

}


void QrcodeGenerate::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];
            //bit0位代表了點的顏色,1表示黑色,0表示白色,我們只要在白背景下畫黑點
            if(b & 0x01)
            {
                QRectF r(x * scale_x, y * scale_y, scale_x, scale_y);
                painter.drawRects(&r, 1);
            }
        }
    }
}

//ui重繪事假
void QrcodeGenerate::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    //把背景設爲純白
    QColor background(Qt::white);
    painter.setBrush(background);
    painter.setPen(Qt::NoPen);
    painter.drawRect(0, 0, width(), height());
    if(qr != NULL)
    {
        draw(painter, width(), height());
    }
}

QSize QrcodeGenerate::sizeHint()  const
{
    QSize s;
    if(qr != NULL)
    {
        int qr_width = qr->width > 0 ? qr->width : 1;
        s = QSize(qr_width * 4, qr_width * 4);
    }
    else
    {
        s = QSize(50, 50);
    }
    return s;
}

QSize QrcodeGenerate::minimumSizeHint()  const
{
    QSize s;
    if(qr != NULL)
    {
        int qr_width = qr->width > 0 ? qr->width : 1;
        s = QSize(qr_width, qr_width);
    }
    else
    {
        s = QSize(50, 50);
    }
    return s;
}

 ②二維碼/條形碼解析

void MainWindow::on_pushButton_clicked()
{
    ui->lineEdit->clear();

    QString filename = QFileDialog::getOpenFileName(this,"file","./","any files(*.*)"";;any files(*.png)");
    QImage img;        //加載圖像
    if(!(img.load(filename)))
    {
        QMessageBox::information(this,"Warning", "Open Picture fail!");
        return;
    }
    img = img.scaled(ui->label->width(),ui->label->height(),Qt::KeepAspectRatio);
    ui->label->setPixmap(QPixmap::fromImage(img));

    QZXing decoder;
    //解析CODE128一維碼和二維碼
    decoder.setDecoder( QZXing::DecoderFormat_CODE_128 | QZXing::DecoderFormat_QR_CODE);
    QString result = decoder.decodeImage(img);
    if(result.isEmpty())
    {
        QMessageBox::about(this,"warning","Wrong picture format!");
        return;
    }

    ui->lineEdit->setText(result);
}

五、源碼Demo

①二維碼生成

鏈接:https://pan.baidu.com/s/1KNcebG_K_ARRkW1tMpbq8g 
提取碼:844t

②二維碼/條形碼解析

鏈接:https://pan.baidu.com/s/1Cr-eBjd3XeADcv7yclvI7g 
提取碼:fr4p

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章