Zint生成多种条码及二维码
也許你的苦思冥想,大神們早已有答案。打開CSDN手機App,看到這么一段話,突然有很多感觸,相信很多小伙伴都有同樣的想法。很多時候,我們都是在干著重復造輪子的事兒,有時是我們當時認知有限,有時是我們太執著。
還記得當時項目需要根據輸入內容實時生成幾種常用的一維條形碼,當時也沒怎么多想,找來一本常用條碼編碼規則的書,照著書上介紹的各種條碼的編碼規則,一步一步通過算法實現了,依稀還記得當初每次實現一個條碼后激動的心情。完成后還得到了老板的表揚,當時心里別提有多舒暢。
再到后來,項目需要根據輸入內容生成二維碼(QR碼),還是老規矩,找來二維碼的編碼規則,看了好久,發現二維碼的編碼規則相對一位條碼來說,復雜了太多,當時心里有點沒底。心想看看網上有沒有類似的生成二維碼的算法,在網上搜索了一下,閱讀了別人寫的一些關于QRcode的文章,最后發現一個qrencode-3.4.4的標準庫。下載后查看了庫的一些用法,結合項目的實際需求,花了大概半天的時間就生成了符合項目需求的二維碼,能夠調用標準庫里提供的API來調整二維碼的屬性。當時心里還在感慨提供這個庫的人真NB,這個庫太好用了!省去了很多二維碼的開發時間。
再后來,項目需要根據輸入內容生成Datamatrix碼,不同以往,我這次連DM碼的編碼規則都沒看,直接在網上搜索相關Datamatrix碼的相關信息,果然,我又發現一個libdmtx-0.7.4的標準庫,還支持中文編碼。沒過多久我又把DM碼給鼓搗出來了。
空閑時,我又在網上搜索了相關條碼以及二維碼生成的相關信息,最后發現了一個功能更加強大的Zint條碼庫。Zint 條碼庫支持目前市場上主流的條碼類型,包括 QR碼、DM碼、code-128碼、EAN13碼等等。最讓我驚喜的是,有大神基于Qt對zint條碼庫進行了一次簡單的封裝,生成條碼的同時對條碼內容的繪制進行了合理的布局,能夠自適應條碼的縮放,這個功能對我來說太有意義了。分享一下,希望對大家有幫助。
具體實現方式也很簡單,在官網上下載最新的ZINT條碼庫,可以直接編譯成動態鏈接庫,當然也可以把源碼嵌入到工程文件直接編譯使用,我使用后者進行測試。
#ifndef BARCODEITEM_H #define BARCODEITEM_H#include <QGraphicsItem> #include <qzint.h>class BarcodeItem : public QGraphicsItem { public:explicit BarcodeItem(QGraphicsItem *parent = Q_NULLPTR);~BarcodeItem();QRectF boundingRect() const;void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0);public:mutable Zint::QZint barcode;Zint::QZint::AspectRatioMode ar;QRectF rect() const;void setRect(const QRectF &rect);inline void setRect(qreal x, qreal y, qreal w, qreal h);struct BarcodeItemProp{int m_symbol;QString m_text;QString m_primaryMessage;int m_height;int m_borderWidth;int m_width;int m_securityLevel;int m_pdf417CodeWords;int m_input_mode;QColor m_fgColor;QColor m_bgColor;QString m_lastError;int m_error;int m_whitespace;zint_symbol * m_zintSymbol;float m_scale;int m_option_3;bool m_hidetext;float m_dot_size;} barcodeItemPara;void drawBarcodeItem(BarcodeItemProp barcodeItemPara);private:QRectF m_rect;mutable QRectF m_boundingRect; };inline void BarcodeItem::setRect(qreal x, qreal y, qreal w, qreal h) {setRect(QRectF(x, y, w, h)); }#endif #include <QDebug> #include "barcodeitem.h"BarcodeItem::BarcodeItem(QGraphicsItem *parent): QGraphicsItem(parent) {setRect(QRectF(0,0,200,200));barcodeItemPara.m_symbol = BARCODE_CODE128;barcodeItemPara.m_hidetext = false;barcodeItemPara.m_text = "6922162891569";barcodeItemPara.m_height = 38;barcodeItemPara.m_scale = 8.0;barcodeItemPara.m_dot_size = 4.0 / 5.0;barcodeItemPara.m_pdf417CodeWords = 928;barcodeItemPara.m_securityLevel = -1;barcodeItemPara.m_input_mode = UNICODE_MODE;barcodeItemPara.m_option_3 = 0;barcodeItemPara.m_width = 0;barcodeItemPara.m_borderWidth = 1; }BarcodeItem::~BarcodeItem() { }QRectF BarcodeItem::boundingRect() const {//return QRectF(0, 0, w, h);if(m_boundingRect.width() == 0){m_boundingRect = QRectF(0,0,800,300);}return m_boundingRect; }void BarcodeItem::paint(QPainter * painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) {barcode.render(*painter,boundingRect(),ar); }QRectF BarcodeItem::rect() const {return m_rect; }void BarcodeItem::setRect(const QRectF &rect) {if(m_rect == rect)return;prepareGeometryChange();m_rect = rect;m_boundingRect = m_rect;update(); }void BarcodeItem::drawBarcodeItem(BarcodeItem::BarcodeItemProp barcodeItemPara) {barcode.setHeight(barcodeItemPara.m_height);barcode.setText(barcodeItemPara.m_text);barcode.setScale(barcodeItemPara.m_scale);barcode.setInputMode(barcodeItemPara.m_input_mode);barcode.setWidth(barcodeItemPara.m_width);barcode.setOption3(barcodeItemPara.m_option_3);barcode.setHideText(barcodeItemPara.m_hidetext);barcode.setDotSize(barcodeItemPara.m_dot_size);barcode.setPdf417CodeWords(barcodeItemPara.m_pdf417CodeWords);barcode.setSymbol(barcodeItemPara.m_symbol);barcode.setSecurityLevel(barcodeItemPara.m_securityLevel);barcode.setBorderWidth(barcodeItemPara.m_borderWidth);barcode.setBorderType(Zint::QZint::NO_BORDER);this->setRect(QRectF(0,0,barcode.width()*barcodeItemPara.m_scale,barcode.height()*barcodeItemPara.m_scale));update(); }?
添加一個繼承QGraphicsItem的類用來繪制條碼及二維碼,主要的是實現方法封裝在qzint類中的render()函數體中,這里就不貼代碼了。具體的調用方法很簡單,設置條碼內容,條碼類別,以及對應條碼相關屬性后,調用drawBarcodeItem()更新條碼信息,調用update()執行paint()完成對barcodeItem的重繪,更新條碼顯示。
?
BarcodeItem *barcode = new BarcodeItem;QGraphicsScene *scene = new QGraphicsScene;QGraphicsView *view = new QGraphicsView;barcode->drawBarcodeItem(barcode->barcodeItemPara);scene->addItem(barcode);view->setScene(scene);QVBoxLayout *vLayout = new QVBoxLayout;QLineEdit *input = new QLineEdit;QComboBox *box = new QComboBox;QStringList barcodeList;barcodeList << "Barcode_128"<< "Barcode_39"<< "EAN13"<< "QRcode"<< "Datamatrix"<< "Pdf147";input->setText(QString("6922162891569"));box->addItems(barcodeList);input->setFixedHeight(50);box->setFixedHeight(50);vLayout->addWidget(view);vLayout->addWidget(input);vLayout->addWidget(box);this->setLayout(vLayout);connect(input,&QLineEdit::textChanged,this,[=](const QString inputStr){barcode->barcodeItemPara.m_text = inputStr;barcode->drawBarcodeItem(barcode->barcodeItemPara);view->update();});connect(box,&QComboBox::currentTextChanged,this,[=](const QString comboStr){if(comboStr == QString("Barcode_128")){barcode->barcodeItemPara.m_symbol = BARCODE_CODE128;}else if(comboStr == QString("Barcode_39")){barcode->barcodeItemPara.m_symbol = BARCODE_CODE39;}else if(comboStr == QString("EAN13")){barcode->barcodeItemPara.m_symbol = BARCODE_EANX;}else if(comboStr == QString("QRcode")){barcode->barcodeItemPara.m_symbol = BARCODE_QRCODE;}else if(comboStr == QString("Datamatrix")){barcode->barcodeItemPara.m_symbol = BARCODE_DATAMATRIX;}else if(comboStr == QString("Pdf147")){barcode->barcodeItemPara.m_symbol = BARCODE_PDF417;}barcode->drawBarcodeItem(barcode->barcodeItemPara);view->update();});這里測試了code_128,code_39,EAN13,qrcode,datamatrix,pdf417,生成6中條碼如下:
看到這里相信大家對ZINT條碼庫的強大已經有目共睹了,有相關需求的可以下載一份ZINT條碼庫研究一下,畢竟重復造輪子這種事兒還是少干為妙。
ps:其實任何事情都要用辨證的角度去看,雖然我當初煞費苦心的研究條碼的編碼規則,通過效率并不高的算法實現了一些常用條碼的生成,但至少我懂了條碼的編碼規則,當客戶需要連續變化的條碼時,我可以很自信的告訴他選擇code_128條碼,當客戶輸入條碼內容和實際生成的條碼掃出來不一致時,我能很確定的告訴客戶你輸入的條碼內容不標準,條碼校驗碼錯了,或許這些就是我最大的收獲吧。
測試程序下載地址:https://download.csdn.net/download/p154613730/10833507
?
總結
以上是生活随笔為你收集整理的Zint生成多种条码及二维码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 人工智能数学基础:利用导数判断函数单调性
- 下一篇: 小程序-相册授权