Qt浅谈之三十二二维码条形码解析

一、简介

        二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的,其应用广泛,如:产品防伪/溯源、广告推送、网站链接、数据下载、商品交易、定位/导航、电子凭证、车辆管理、信息传递、名片交流、wifi共享等。
     一维码是用条空在水平方向上表达信息的条码,外形更接近矩形;二维码可以说是正方形,在其内部有三个“回”字型的定位点,可以帮助条码设备对焦,便于读取数据。一维码的信息部分只能是字母和数字,它的数据容量较小一般只可容纳30个字符左右。二维码的信息承载量很大,最大数据含量可达1850个字符,信息内容可包含,字母,数字,汉字,字符,片假名等。一维码的常用码制包括:EAN码、39码、交叉25码、UPC码、128码、93码,ISBN码,及Codabar(库德巴码)等;二维码常用的码制有:PDF417二维条码,Datamatrix二维条码,QR Code,Code 49,Code 16K,Code one等。

二、详解

1、libqrencode库(生成二维码)

(1)qrcodewidget.h

 

#ifndef QRCODE_H
#define QRCODE_H

#include <QWidget>
#include <QTextCodec>

namespace Ui {
class QRCode;
}

class QRCodeWidget : public QWidget
{
    Q_OBJECT

public:
    explicit QRCodeWidget(QWidget *parent = 0);
    ~QRCodeWidget();

private slots:
    void on_pushButton_clicked();

private:
    Ui::QRCode *ui;
};

#endif // QRCODE_H

 

(2)qrcodewidget.cpp

 

#include <QPicture>
#include "qrcodewidget.h"
#include "ui_qrcode.h"
#include "qrencode.h"
#include "qrenc.c"

QRCodeWidget::QRCodeWidget(QWidget *parent) :
    QWidget(parent, Qt::Dialog),
    ui(new Ui::QRCode)
{
    QTextCodec *codec = QTextCodec::codecForName("utf8");
    QTextCodec::setCodecForLocale(codec);
    QTextCodec::setCodecForCStrings(codec);
    QTextCodec::setCodecForTr(codec);
    ui->setupUi(this);
}

QRCodeWidget::~QRCodeWidget()
{
    delete ui;
}

void QRCodeWidget::on_pushButton_clicked()
{
    QString info = ui->lineEdit->text();
    if (info.isEmpty()) {
        return;
    }
    char outfile[] = "output.png";
    margin = 2;
    ::size = 7;
    version = 2;
    //QRcode *qrcode = QRcode_encodeString(info.toStdString().data(), 2, QR_ECLEVEL_L, QR_MODE_8, 0);
    //writePNG(qrcode, outfile);

    qrencode((unsigned char *)info.toStdString().data(), info.length(), outfile);
    ui->label_3->setPixmap(QPixmap(outfile));
}

(3)main.cpp

 

#include "qrcodewidget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QRCodeWidget w;
    w.show();

    return a.exec();
}

 

(4)运行

           

       也可是使用QrenCode 的命令行工具生成二维码,在centos6.6下执行# yum install qrencode(或下载qrencode-3.4.4.tar.gz使用./configure、make、make install安装);使用qrencode -o output.png https://www.baidu.com/即可在当前目录下生成百度的二维码图片output.png;若想自定义尺寸的话,加上 -s 参数,比如 -s 6 表示尺寸为 6x6 平方像表大小,qrencode -s 6 -o output.png https://www.baidu.com/。命令行下识别二维码的是#yum install libdecodeqr-examples,libdecodeqr-simpletest <二维码图片>。安装zbar-0.10.tar.bz2,也可一识别二维码。

      

(5)源码可从csdn上下载:http://download.csdn.net/detail/taiyang1987912/8991975

 

2、zbar库(识别二维码)

 

      下载http://sourceforge.net/projects/zbar/files/?source=navbar的源码:zbar-0.10.tar.bz2,执行./configure和make和make install安装zbar,默认安装头文件在/usr/local/include下,库文件在/usr/local/lib。
(1)qrcodezbar.h

 

#ifndef QRCODEZBAR_H
#define QRCODEZBAR_H

#include <QWidget>
#include <QTextCodec>
#include <QFileDialog>
#include <zbar/QZBar.h>

namespace Ui {
class QZbar;
}


class QRCodeZbar : public QWidget
{
    Q_OBJECT

public:
    QRCodeZbar(QWidget *parent = 0);
    ~QRCodeZbar();

private:


private slots:
    void on_pushButton_clicked();

private:
    Ui::QZbar *ui;
    zbar::QZBar *qz;
};

#endif // QRCODEZBAR_H

(2)qrcodezbar.cpp

#include "qrcodezbar.h"
#include "ui_qzbar.h"
#include "scanimage.h"
#ifdef QRDECODE
    #include "scanimagemagick.h"
#endif

QRCodeZbar::QRCodeZbar(QWidget *parent)
    : QWidget(parent, Qt::Dialog)
    , ui(new Ui::QZbar)
{
    QTextCodec *codec = QTextCodec::codecForName("utf8");
    QTextCodec::setCodecForLocale(codec);
    QTextCodec::setCodecForCStrings(codec);
    QTextCodec::setCodecForTr(codec);
    ui->setupUi(this);
}

QRCodeZbar::~QRCodeZbar()
{

}

void QRCodeZbar::on_pushButton_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("choose a picture"),
                                                    QApplication::applicationDirPath(),
                                                    tr("all Files (*.*)"));
    ui->lineEdit->setText(fileName);
    ui->label_3->setPixmap(QPixmap(ui->lineEdit->text()));
    char result[1024] = {0};
    #ifdef QRDECODE
        scanimagemagick(ui->lineEdit->text().toStdString().data(), result);
    #else
        scanimage(ui->lineEdit->text().toStdString().data(), result);
    #endif
    ui->textEdit->setText(result);
}

(3)scanimagemagick.h

 

#ifndef SCANIMAGEMAGICK_H
#define SCANIMAGEMAGICK_H
#include <iostream>
#include <Magick++.h>
#include <zbar.h>
#define STR(s) #s
/*****************
 * yum install ImageMagick
 ***********/
using namespace std;
using namespace zbar;

int scanimagemagick (const char *filename, char *result);

#endif // SCANIMAGE_H

(4)scanimagemagick.cpp

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "scanimagemagick.h"

int scanimagemagick(const char *filename, char *result)
{
#ifdef MAGICK_HOME
    // http://www.imagemagick.org/Magick++/
    //    under Windows it is necessary to initialize the ImageMagick
    //    library prior to using the Magick++ library
    Magick::InitializeMagick(MAGICK_HOME);
#endif

    // create a reader
    ImageScanner scanner;

    // configure the reader
    scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);

    // obtain image data
    Magick::Image magick(filename);  // read an image file
    int width = magick.columns();   // extract dimensions
    int height = magick.rows();
    Magick::Blob blob;              // extract the raw data
    magick.modifyImage();
    magick.write(&blob, "GRAY", 8);
    const void *raw = blob.data();

    // wrap image data
    Image image(width, height, "Y800", raw, width * height);

    // scan the image for barcodes
    int n = scanner.scan(image);

    // extract results
    for(Image::SymbolIterator symbol = image.symbol_begin();
        symbol != image.symbol_end();
        ++symbol) {
        // do something useful with results
//        cout << "decoded " << symbol->get_type_name()
//             << " symbol \"" << symbol->get_data() << '"' << endl;
        sprintf(result, "%s:%s", symbol->get_type_name().data(), symbol->get_data().data());
    }

    // clean up
    image.set_data(NULL, 0);

    return(0);
}

(5)运行结果
 
(6)源码可从csdn上下载:http://download.csdn.net/detail/taiyang1987912/9001133
(7)提示
       打开编译选项DEFINES *= QRDECODE,则使用了ImageMagick,则需要安装#yum install ImageMagick,并加入头文件路径/usr/include/ImageMagick/。若不是用QRDECODE,用C库,再识别有些png文件时会出现段错误。上述zbar有中文乱码,可参考网上修改。

 

3、QZxing库(识别二维码)

 

        从http://sourceforge.net/projects/qzxing/files/下载QZxing的decoding library的源码,在工程中加入include(QZXing_sourceV2.3/QZXing.pri)。
(1)qrcondezxing.h

#ifndef QRCONDEZXING_H
#define QRCONDEZXING_H

#include <QWidget>
#include <QTextCodec>
#include <QFileDialog>

namespace Ui {
class QRCondeZxing;
}

class QRCondeZxing : public QWidget
{
    Q_OBJECT

public:
    explicit QRCondeZxing(QWidget *parent = 0);
    ~QRCondeZxing();

private slots:
    void on_pushButton_clicked();

private:
    Ui::QRCondeZxing *ui;
};

#endif // QRCONDEZXING_H

(2)qrcondezxing.cpp

 

#include "qrcondezxing.h"
#include "ui_qrcondezxing.h"
#include "QZXing.h"

QRCondeZxing::QRCondeZxing(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::QRCondeZxing)
{
    QTextCodec *codec = QTextCodec::codecForName("utf8");
    QTextCodec::setCodecForLocale(codec);
    QTextCodec::setCodecForCStrings(codec);
    QTextCodec::setCodecForTr(codec);
    ui->setupUi(this);
}

QRCondeZxing::~QRCondeZxing()
{
    delete ui;
}

void QRCondeZxing::on_pushButton_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("choose a picture"),
                                                    QApplication::applicationDirPath(),
                                                    tr("all Files (*.*)"));
    ui->lineEdit->setText(fileName);
    ui->label_3->setPixmap(QPixmap(ui->lineEdit->text()));
    QZXing decoder;
    QString qrmsg = decoder.decodeImageFromFile(ui->lineEdit->text());
    ui->textEdit->setText(qrmsg);
}

(3)运行结果:

 

 

(4)源码可从csdn上下载:http://download.csdn.net/detail/taiyang1987912/8991903

三、条形码/二维码开源软件

 

 

(1)二维码扫描工具和开发包ZBar
        ZBar是款桌面电脑用条形码/二维码扫描工具,支持摄像头及图片扫描,支持多平台包括 iPhone 手机。同时 ZBar 提供了二维码扫描的 API 开发包。 ZBar 目前支持扫描,除了 Windows 平台外,还支持 Linux 及 iPhone 平台。网址:http://zbar.sourceforge.net
(2)C语言二维条形码解析库libqrencode
        libqrencode (QRencode) 是一个用C语言编写的用来解析二维条形码(QR Code)的程序库,libqrencode通过手机的CCD摄像头来扫描二维条形码。网址:http://zbar.sourceforge.net
(3)条形码扫描软件 Zebra barcode reader
        Zebra barcode reader是一个小型的,分层次的条形码扫描软件。它支持许多流行的条码符号:EAN,UPC,128码,39码等。能抓获条码解码图像和使用视频设备(如摄像头)作为一个条形码扫描仪。
(4)QZXing

 

        Qt包装ZXing的解码库。ZXing是条形码处理类库,它是一个开源Java类库用于解析多种格式的1D/2D条形码。目标是能够对QR编码、Data Matrix、UPC的1D条形码进行解码。 其提供了多种平台下的客户端包括:J2ME、J2SE和Android。网址:http://sourceforge.net/projects/qzxing
       其他参考:http://www.oschina.net/project/tag/238/barcode
http://www.oschina.net/project/tag/238/barcode?lang=21&sort=v-

四、总结

(1)二维码和条形码的开源软件种类很多,可针对C、Java、ios等不同接口来选择自己的需求。
(2)二维码的库在中文方面的也是有支持的。
(3)源码使用中仅仅进行了简单的调用,没有实现更深层次的开发,主要是自己没有项目需求,其他的开发读者可继续开发。
(4)若有建议,请留言,在此先感谢!

  • 1
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论
Qt 是一款跨平台的应用程序开发框架,提供了丰富的工具和库,能够帮助开发者快速解析二进制数据。 在 Qt 中,可以使用 QByteArray 类来处理二进制数据。QByteArray 是 Qt 提供的一种动态数组类型,能够方便地存储和处理字节数组。通过 QByteArray,我们可以轻松地读取和操作二进制文件。 首先,我们需要将二进制数据读入到 QByteArray 中。可以使用 QFile 类打开二进制文件,并利用其 readAll() 函数将文件中的所有内容读取到 QByteArray 中。 一旦二进制数据被读入到 QByteArray 中,我们就可以使用 QByteArray 类中的函数来解析它。常用的函数包括 at()、mid()、left() 和 right()。通过这些函数,我们可以按照需要提取出二进制数据中的指定部分,并进一步对其进行处理。 除了 QByteArray,Qt 还提供了 QDataStream 类,它是对 QByteArray 进行高级操作的帮助类。QDataStream 提供了许多便捷的函数,用于将二进制数据解析为各种不同类型的数据,如整数、浮点数、字符串等。通过使用 QDataStream,我们可以更加方便地对二进制数据进行解析和读取。 总结起来,Qt 提供了丰富的工具和库,能够帮助开发者快速解析二进制数据。通过 QByteArray 和 QDataStream,我们可以方便地读取、解析和操作二进制数据中的内容,从而实现各种二进制数据的处理需求。无论是读取二进制文件、解析网络数据还是对二进制数据进行加工,Qt 都能够提供强大的支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乌托邦2号

博文不易,支持的请给予小小打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值