Qt專案實戰3:二維碼生成器
阿新 • • 發佈:2018-12-20
qrtool專案簡介
二維碼(Qrcode)現在越來越常用,掃碼支付、掃碼新增好友、掃碼乘坐公交車和地鐵,我們的生活已經與二維碼息息相關。這裡我們使用qt軟體+qrencode開源庫來生成、顯示、儲存二維碼圖片,並且支援簡單的二維碼容錯率修改和大小修改。 ui效果圖如下:
qrencode開源庫
libqrencode
是生成二維碼資料的開源庫。 github連結 。
在Windows平臺,使用CMake工具構建libqrencode工程,生成靜態庫,在qt工程中使用。
構建qrencode工程
安裝cmake工具 官網下載連結。 使用cmake構建工程 修改工程配置資訊: 這裡需要注意的是,構建qrencode庫,不關聯iconv和libpng庫。 使用Configure命令生成工程配置檔案,使用Generate命令生成Makefile檔案,構建完成。
編譯libqrencode庫
構建完成後,進入命令列,進行編譯:
Microsoft Windows [版本 10.0.17134.228]
(c) 2018 Microsoft Corporation。保留所有權利。
C:\Users\Administrator> cd /d E:\opensource\libqrencode-master\build
E:\opensource\libqrencode-master\build>mingw32-make
-- Could NOT find ZLIB (missing: ZLIB_LIBRARY ZLIB_INCLUDE_DIR)
-- Could NOT find PNG (missing: PNG_LIBRARY PNG_PNG_INCLUDE_DIR)
-- Could NOT find ICONV (missing: ICONV_FOUND_ANY ICONV_INCLUDE_DIR)
-- ------------------------------------------------------------
-- [QRencode] Configuration summary.
-- ------------------------------------------------------------
-- System configuration:
-- .. Processor type .............. = AMD64
-- .. CMake executable ............ = D:/Program Files/CMake/bin/cmake.exe
-- .. CMake version ............... = 3.12.1
-- .. System name ................. = Windows-10.0.17134
-- .. C++ compiler ................ =
-- .. C compiler .................. = D:/software/Qt/Qt5.6.0/Tools/mingw492_32/bin/gcc.exe
-- .. size(void*) ................. = 4
-- Dependencies:
-- .. Thread library of the system =
-- .. Iconv ....................... = FALSE
-- .... Iconv includes ............ = ICONV_INCLUDE_DIR-NOTFOUND
-- .... Iconv library ............. = ICONV_LIBRARY-NOTFOUND
-- .. ZLIB ........................ = FALSE
-- .. PNG ......................... = FALSE
-- .... PNG includes .............. =
-- .... PNG library ............... =
-- Project configuration:
-- .. Build test programs ........ = OFF
-- .. Build utility tools ........ = OFF
-- .. Disable PNG support ........ = OFF
-- .. Installation prefix ......... = E:/opensource/libqrencode-master/install
-- ------------------------------------------------------------
-- Configuring done
-- Generating done
-- Build files have been written to: E:/opensource/libqrencode-master/build
Scanning dependencies of target qrencode
[ 10%] Building C object CMakeFiles/qrencode.dir/qrencode.c.obj
[ 20%] Building C object CMakeFiles/qrencode.dir/qrinput.c.obj
[ 30%] Building C object CMakeFiles/qrencode.dir/bitstream.c.obj
[ 40%] Building C object CMakeFiles/qrencode.dir/qrspec.c.obj
[ 50%] Building C object CMakeFiles/qrencode.dir/rsecc.c.obj
[ 60%] Building C object CMakeFiles/qrencode.dir/split.c.obj
[ 70%] Building C object CMakeFiles/qrencode.dir/mask.c.obj
[ 80%] Building C object CMakeFiles/qrencode.dir/mqrspec.c.obj
[ 90%] Building C object CMakeFiles/qrencode.dir/mmask.c.obj
[100%] Linking C static library libqrencode.a
[100%] Built target qrencode
E:\opensource\libqrencode-master\build>mingw32-make install
[100%] Built target qrencode
Install the project...
-- Install configuration: ""
-- Up-to-date: E:/opensource/libqrencode-master/install/share/man/man1/qrencode.1
-- Up-to-date: E:/opensource/libqrencode-master/install/lib/pkgconfig/libqrencode.pc
-- Up-to-date: E:/opensource/libqrencode-master/install/include/qrencode.h
-- Installing: E:/opensource/libqrencode-master/install/lib/libqrencode.a
E:\opensource\libqrencode-master\build>
使用mingw32-make
和mingw32-make install
命令編譯和安裝庫檔案。安裝完成後,將生成的libqrencode庫拷貝到qt工程中以供使用。
生成二維碼資料
使用QRcode_encodeString
函式來生成二維碼資料,函式原型如下:
QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
引數string表示需要轉換的資料,QRecLevel和QRencodeMode列舉型別如下所示。casesensitive表示是否使能大小寫敏感,預設啟用就可以了。
/**
* Level of error correction.
*/
typedef enum {
QR_ECLEVEL_L = 0, ///< lowest
QR_ECLEVEL_M,
QR_ECLEVEL_Q,
QR_ECLEVEL_H ///< highest
} QRecLevel;
/**
* Encoding mode.
*/
typedef enum {
QR_MODE_NUL = -1, ///< Terminator (NUL character). Internal use only
QR_MODE_NUM = 0, ///< Numeric mode
QR_MODE_AN, ///< Alphabet-numeric mode
QR_MODE_8, ///< 8-bit data mode
QR_MODE_KANJI, ///< Kanji (shift-jis) mode
QR_MODE_STRUCTURE, ///< Internal use only
QR_MODE_ECI, ///< ECI mode
QR_MODE_FNC1FIRST, ///< FNC1, first position
QR_MODE_FNC1SECOND, ///< FNC1, second position
} QRencodeMode;
encode成功後,返回QRcode結構體資料:
/**
* QRcode class.
* Symbol data is represented as an array contains width*width uchars.
* Each uchar represents a module (dot). If the less significant bit of
* the uchar is 1, the corresponding module is black. The other bits are
* meaningless for usual applications, but here its specification is described.
*
* @verbatim
MSB 76543210 LSB
|||||||`- 1=black/0=white
||||||`-- 1=ecc/0=data code area
|||||`--- format information
||||`---- version information
|||`----- timing pattern
||`------ alignment pattern
|`------- finder pattern and separator
`-------- non-data modules (format, timing, etc.)
@endverbatim
*/
typedef struct {
int version; ///< version of the symbol
int width; ///< width of the symbol
unsigned char *data; ///< symbol data
} QRcode;
使用encode轉換的data和width資料,即可繪製出二維碼圖片。
繪製二維碼圖片
在Qt中,使用QImage類來建立一個圖片例項,使用QPainter類來繪製圖片。 繪製圖片步驟:
- 建立QPainter例項,在已經存在的image例項上繪製
- 建立一張空白的畫布
- 使用黑色畫刷,根據資料寬度畫畫素矩形
- 將二維碼生成的資料填充在畫布上
void Widget::genQrcodeImage(char *qr_str, int width, int height)
{
QRcode *qrcode = NULL;
if (qr_str == NULL || width <= 0 || height <= 0)
return ;
qrcode = QRcode_encodeString(qr_str, qrcode_version, QR_ECLEVEL_M, QR_MODE_8, 1);
if(qrcode != NULL) {
QPainter painter(image);
unsigned char *point = qrcode->data;
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::white);
painter.drawRect(0, 0, width, height);
double scale = (width - 2.0 * margin) / qrcode->width;
painter.setBrush(Qt::black);
for (int y = 0; y < qrcode->width; y++) {
for (int x = 0; x < qrcode->width; x++) {
if (*point & 1) {
QRectF r(margin + x * scale, margin + y * scale, scale, scale);
painter.drawRects(&r, 1);
}
point++;
}
}
point = NULL;
QRcode_free(qrcode);
qrcode = NULL;
}
}
繪製完成後,在QLabel上顯示圖片:
QPixmap pixmap = QPixmap::fromImage(*image);
ui->qrLabel->setPixmap(pixmap);