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,也可一識別二維碼。
2、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)
(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)執行結果:
三、條形碼/二維碼開源軟體
(1)二維碼掃描工具和開發包ZBarZBar是款桌面電腦用條形碼/二維碼掃描工具,支援攝像頭及圖片掃描,支援多平臺包括 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
四、總結
(1)二維碼和條形碼的開源軟體種類很多,可針對C、Java、ios等不同介面來選擇自己的需求。(2)二維碼的庫在中文方面的也是有支援的。
(3)原始碼使用中僅僅進行了簡單的呼叫,沒有實現更深層次的開發,主要是自己沒有專案需求,其他的開發讀者可繼續開發。
(4)若有建議,請留言,在此先感謝!