900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 应用笔记-Qt 程序中使用 Live 20R 指纹采集器

应用笔记-Qt 程序中使用 Live 20R 指纹采集器

时间:2021-01-14 22:13:56

相关推荐

应用笔记-Qt 程序中使用 Live 20R 指纹采集器

应用笔记-Qt 程序中使用 Live 20R 指纹采集器

最近一个项目需要用到指纹认证。就在某东上随便搜了个销量比较大的指纹采集器,就是今天这个笔记的主角(Live 20R 指纹采集器)。花了几天时间研究明白了这个小东西是如何使用的。

Live 20R 指纹采集器本身提供了 SDK 开发包,叫做 ZKFinger SDK,我使用的版本是 5.0。这个 SDK 里提供了 ActiveX 接口和 C 语言接口。比较这两个接口的功能会发现 ActiveX 接口提供的功能更强,因此,应该优先使用这个接口。

不过我当时没仔细对比,直接就用了 SDK 中提供的 C 语言接口了。这个功能少了点,但是也够我用了。

简单的说,Live 20R 指纹采集器本身只是个指纹图像获取设备。它可以用来获取指纹图像。其他的功能都是 SDK 软件来实现的。因此我将功能划分到了两个 C++类中:

FingerprintReaderFingerprintCacheDB

FingerprintReader 用于获取指纹。FingerprintCacheDB 实现指纹比对等其他功能。另外还有两个辅助类:

FingerprintEnrollFPCacheDBLoader

FingerprintEnroll 是个辅助类,用于简化指纹登记的代码。FPCacheDBLoader 用于将指纹存入数据库或从数据库中读出。

FingerprintReader

FingerprintReader 这个类直接与硬件打交道。用于获取指纹。里面用到了一个线程,不停的询问Live 20R 指纹采集器是否有新的指纹,如果有则发出一个 Qt 信号 :void onFingerprintReceived(QImage image, QByteArray fpTemplate)。

QByteArray fpTemplate 是从指纹中提取的信息。后面的比对都是用的这个 fpTemplate。指纹图像在后面倒是没什么用的。这里之所以把指纹图像给传出来了,主要是为了在界面上显示出来,看起来比较的酷。

下面直接给代码吧,首先是头文件:

#ifndef FINGERPRINTREADER_H#define FINGERPRINTREADER_H#include <QObject>#include <QThread>#include <QImage>#include <QString>#include <windows.h>namespace ZKFP{/*** @brief The FingerprintReader class 这个类完成指纹采集的工作。指纹判别工作由其他类来完成。*/class FingerprintReader : public QThread{Q_OBJECTpublic:explicit FingerprintReader(QObject *parent = nullptr);~FingerprintReader();/*** @brief getDeviceCount 获取系统中识别出来的指纹识别器的数量* @return*/int getDeviceCount();QImage acquireImage();QString vendorName() const;QString productName() const;QString serialNumber() const;uint16_t getVID() const;uint16_t getPID() const;bool isFakeFuncOn();QSize imageSize() {return QSize(m_image_width, m_image_height);}signals:/*** @brief onFeatureInfo 取得指纹初始特征时发出该信号* @param quality 表示该指纹特征的质量*0: 好的指纹特征, 1: 特征点不够, 2: 其它原因导致不能取到指纹特征, -1: 可疑*/void onFeatureInfo(int quality);/*** @brief onFingerTouching 当手指按压纹取像设备时发送该信号。*/void onFingerTouching();/*** @brief onFingerLeaving 当手离开压纹取像设备时发送该信号。*/void onFingerLeaving();void onCapture(bool result);void onFingerprintReceived(QImage image, QByteArray fpTemplate);void fakeFinger();public slots:bool openDevice(int index = 0);void closeDevice();void beginCapture();void cancelCapture();/*** @brief setFakeFunc 设置防假开关* @param on true 表示开启防假指纹功能。 false 表示关闭防假指纹功能。*/void setFakeFunc(bool on);private:HANDLE m_handle;QString m_vendorName;QString m_productName;QString m_serialNumber;QImage m_fpImage;int m_image_width;int m_image_height;int m_image_size;int m_image_DPI;int m_isFakeOn;uint16_t m_vid;uint16_t m_pid;bool m_init;void run() override;bool isRealFinger();bool m_stop;};}#endif // FINGERPRINTREADER_H

接下来是 cpp 文件:

#include "FingerprintReader.h"#include "FingerprintCacheDB.h"#include "ZKFingerReader/libs/include/libzkfp.h"#include <QDebug>namespace ZKFP{static const int ZKFP_IMAGE_WIDTH_RO = 1;static const int ZKFP_IMAGE_HEIGHT_RO = 2;static const int ZKFP_IMAGE_DPI_RW = 3;static const int ZKFP_IMAGE_SIZE_RO = 106;static const int ZKFP_VID_PID_RO = 1015;static const int ZKFP_FAKE_ON_RW = 2002;static const int ZKFP_REAL_FINGER_RO = ;static const int ZKFP_VENDOR_NAME_RO = 1101;static const int ZKFP_PRODUCT_NAME = 1102;static const int ZKFP_SERIAL_NUNBER = 1103;//static const int MAX_TEMPLATE_SIZE = 2048;static const int ZKFP_ERR_OK = 0;int autoInitCount = 0;static bool autoInit(){if(autoInitCount == 0){if( ZKFPM_Init() == 0){autoInitCount ++;return true;}else{return false;}}return true;}static bool autoTerminate(){autoInitCount --;if(autoInitCount == 0){return (ZKFPM_Terminate() == 0);}return false;}FingerprintReader::FingerprintReader(QObject *parent): QThread(parent),m_init(false),m_handle(0),m_image_height(0),m_image_width(0),m_image_size(0),m_vendorName(""),m_productName(""),m_serialNumber(""),m_stop(true){m_init = autoInit();qDebug() << "autoInit = " << m_init;}int FingerprintReader::getDeviceCount(){return ZKFPM_GetDeviceCount();}bool FingerprintReader::openDevice(int index){m_handle = ZKFPM_OpenDevice(index);if(m_handle != 0){setFakeFunc(true);unsigned int length = sizeof(int);m_image_DPI = 500;length = sizeof(int);ZKFPM_SetParameters(m_handle, ZKFP_IMAGE_DPI_RW, reinterpret_cast<unsigned char *> (&m_image_DPI), length);length = sizeof(int);ZKFPM_GetParameters(m_handle, ZKFP_IMAGE_DPI_RW, reinterpret_cast<unsigned char *> (&m_image_DPI), &length);ZKFPM_GetParameters(m_handle, ZKFP_IMAGE_WIDTH_RO, reinterpret_cast<unsigned char *> (&m_image_width), &length);length = sizeof(int);ZKFPM_GetParameters(m_handle, ZKFP_IMAGE_HEIGHT_RO, reinterpret_cast<unsigned char *> (&m_image_height), &length);length = sizeof(int);ZKFPM_GetParameters(m_handle, ZKFP_IMAGE_SIZE_RO, reinterpret_cast<unsigned char *> (&m_image_size), &length);qDebug() << "image width = " << m_image_width << ", height = " << m_image_height << ", DPI = " << m_image_DPI;char name[128] = {0};memset(name, 0, 128);length = 128;ZKFPM_GetParameters(m_handle, ZKFP_VENDOR_NAME_RO, reinterpret_cast<unsigned char *>(name), &length);m_vendorName.clear();m_vendorName.append(name);memset(name, 0, 128);length = 128;ZKFPM_GetParameters(m_handle, ZKFP_PRODUCT_NAME, reinterpret_cast<unsigned char *>(name), &length);m_productName.clear();m_productName.append(name);memset(name, 0, 128);length = 128;ZKFPM_GetParameters(m_handle, ZKFP_SERIAL_NUNBER, reinterpret_cast<unsigned char *>(name), &length);m_serialNumber.clear();m_serialNumber.append(name);qDebug() << "Vendor Name = " << m_vendorName;qDebug() << "Product Name = " << m_productName;qDebug() << "Serial Number = " << m_serialNumber;uint16_t vid_pid[2] = {0, 0};length = 4;ZKFPM_GetParameters(m_handle, ZKFP_VID_PID_RO, reinterpret_cast<unsigned char *>(vid_pid), &length);m_vid = vid_pid[0];m_pid = vid_pid[1];qDebug() << "VID = " << m_vid << ", PID = " << m_pid;return true;}else{m_vendorName.clear();m_productName.clear();m_serialNumber.clear();m_vid = 0;m_pid = 0;}return false;}bool FingerprintReader::isFakeFuncOn(){m_isFakeOn = 0;unsigned int length = sizeof(m_isFakeOn);ZKFPM_GetParameters(m_handle, ZKFP_FAKE_ON_RW, reinterpret_cast<unsigned char *>(&m_isFakeOn), &length);return m_isFakeOn;}void FingerprintReader::setFakeFunc(bool on){int fakeON = on ? 1 : 0;unsigned int length = sizeof(m_isFakeOn);ZKFPM_SetParameters(m_handle, ZKFP_FAKE_ON_RW, reinterpret_cast<unsigned char *> (&fakeON), sizeof(int));ZKFPM_GetParameters(m_handle, ZKFP_FAKE_ON_RW, reinterpret_cast<unsigned char *>(&m_isFakeOn), &length);}void FingerprintReader::closeDevice(){if(isRunning()){cancelCapture();}if(m_handle){ZKFPM_CloseDevice(m_handle);m_vendorName.clear();m_productName.clear();m_serialNumber.clear();m_image_height = 0;m_image_width = 0;m_image_size = 0;m_vid = 0;m_pid = 0;m_handle = 0;}}QImage FingerprintReader::acquireImage(){int width, height;uint length = 4;ZKFPM_GetParameters(m_handle, 1, (unsigned char*)&width, &length);ZKFPM_GetParameters(m_handle, 2, (unsigned char*)&height, &length);QImage image(width, height, QImage::Format_Grayscale8);ZKFPM_AcquireFingerprintImage(m_handle, image.bits(), width * height);return image;}QString FingerprintReader::vendorName() const{return m_vendorName;}QString FingerprintReader::productName() const{return m_productName;}QString FingerprintReader::serialNumber() const{return m_serialNumber;}uint16_t FingerprintReader::getVID() const{return m_vid;}uint16_t FingerprintReader::getPID() const{return m_pid;}bool FingerprintReader::isRealFinger(){int nFakeStatus = 0;unsigned int retLen = sizeof(int);if (0 == ZKFPM_GetParameters(m_handle, ZKFP_REAL_FINGER_RO, (unsigned char*)&nFakeStatus, &retLen)){if ((nFakeStatus & 31) == 31){return true;}}return false;}void FingerprintReader::run(){qDebug() << "Fingerprint sensor thead starting";unsigned char * imageBuffer = new unsigned char[m_image_height * m_image_width + 100];QImage image(m_image_width, m_image_height, QImage::Format_Grayscale8); //image 要求数据是 32位对齐的。unsigned char fpBuffer[MAX_TEMPLATE_SIZE];unsigned int tempLen = MAX_TEMPLATE_SIZE;while(!m_stop){tempLen = MAX_TEMPLATE_SIZE;int ret = ZKFPM_AcquireFingerprint(m_handle, imageBuffer, m_image_size, fpBuffer, &tempLen);//qDebug() << "AcquireFingerprint = " << ret;if (0 == ret){qDebug() << "AcquireFingerprint = " << ret;qDebug() << "Template size = " << tempLen;if ( m_isFakeOn && !isRealFinger() ) //FakeFinger Test{emit fakeFinger();qDebug() << "fakeFinger";}else{for(int i = 0; i < m_image_height; i++){unsigned char * to = image.scanLine(i);unsigned char * from = imageBuffer + i * m_image_width;memcpy(to, from, m_image_width);}QByteArray pfTemplate(reinterpret_cast<char *>(fpBuffer), tempLen);//fpTemplate.truncate(tempLen);emit onFingerprintReceived(image, pfTemplate);qDebug() << "emit onImageReceived(image, fpTemplate)";}}Sleep(100);}qDebug() << "Fingerprint sensor thead stoped";}void FingerprintReader::beginCapture(){if(m_init && m_handle){m_stop = false;}start();}void FingerprintReader::cancelCapture(){m_stop = true;}FingerprintReader::~FingerprintReader(){if(m_handle){closeDevice();}autoTerminate();}}

FingerprintCacheDB

FingerprintCacheDB 类用于实现指纹的比对。 SDK 中提供的功能包括 1 对 1 的比对,和 1 对 N 的识别。所谓 1 对 N 指的是提前在 FingerprintCacheDB 类里加载 N 个指纹数据。然后提供一个新的指纹,判断这个指纹是否和那 N 个指纹中的某一个是同一个指纹。

下面还是直接给代码吧,首先是头文件:

#ifndef FINGERPRINTCACHEDB_H#define FINGERPRINTCACHEDB_H#include <QObject>#include <windows.h>namespace ZKFP{QString BlobToBase64(QByteArray regTemplate);QByteArray Base64ToBlob(QString base64String);/*** @brief The FingerprintCacheDB class 指纹识别类,用来进行 1:N 的指纹识别。**/class FingerprintCacheDB : public QObject{Q_OBJECTpublic:FingerprintCacheDB(QObject *parent = nullptr);~FingerprintCacheDB();/*** @brief verifyFinger 比较两个指纹是否是同一个手指的* @param regTemplate 指纹 1* @param verTemplate 指纹 2* @return 0 - 100 分数越高表明匹配度越好*/int verifyFinger(QByteArray regTemplate, QByteArray verTemplate);/*** @brief mergeFinger 将三个指纹模板合并成一个* @param inTemplate1* @param inTemplate2* @param inTemplate3* @param outTemplate* @return*/int mergeFinger(QByteArray inTemplate1, QByteArray inTemplate2, QByteArray inTemplate3, QByteArray &outTemplate);int identify(QByteArray inTemplate, unsigned int &fingerID, unsigned int &score);int identify(QString base64String, unsigned int &fingerID, unsigned int &score);/*** @brief count 返回指纹数据库中的数据条数* @return*/int count() const;public slots:/*** @brief clearAll 清空指纹数据库* @return*/int clearAll();/*** @brief deleteItem 删除 fingerID 对应的数据* @param fingerID* @return*/int deleteItem(unsigned int fingerID);/*** @brief addItem 将一个指纹模板登记到指纹数据库中,同时设置这个指纹模板的 ID 为 fingerID.* @param fingerID* @param regTemplate* @return*/int addItem(unsigned int fingerID, QByteArray regTemplate);int addItem(unsigned int fingerID, QString base64String);private:HANDLE m_hDBCache;//缓存区句柄};}#endif // FINGERPRINTCACHEDB_H

然后是 cpp 文件:

#include "FingerprintCacheDB.h"#include "ZKFingerReader/libs/include/libzkfp.h"#include <QDebug>namespace ZKFP{QString BlobToBase64(QByteArray regTemplate){int size = (regTemplate.size() * 8 + 5 )/ 6;char * str = new char[size + 1];memset(str, 0, size + 1);ZKFPM_BlobToBase64(reinterpret_cast<unsigned char *>(regTemplate.data()), regTemplate.size(),str, size + 1);QString ret(str);// QString ret2 = regTemplate.toBase64();// if(ret == ret2)// {// qDebug() << "base64 is same";// }delete []str;return ret;}QByteArray Base64ToBlob(QString base64String){int size = base64String.size() * 6 / 8;unsigned char *blob = new unsigned char[size];int length = ZKFPM_Base64ToBlob(reinterpret_cast<char *> (base64String.data()), blob, size);QByteArray ret(reinterpret_cast<char*> (blob), length);delete [] blob;return ret;}FingerprintCacheDB::FingerprintCacheDB(QObject *parent):QObject(parent),m_hDBCache(0){m_hDBCache = ZKFPM_DBInit();}FingerprintCacheDB::~FingerprintCacheDB(){ZKFPM_DBFree(m_hDBCache);}int FingerprintCacheDB::clearAll(){return ZKFPM_DBClear(m_hDBCache);}int FingerprintCacheDB::addItem(unsigned int fingerID, QString base64String){QByteArray blob = Base64ToBlob(base64String);return addItem(fingerID, blob);}int FingerprintCacheDB::addItem(unsigned int fingerID, QByteArray regTemplate){return ZKFPM_DBAdd(m_hDBCache, fingerID, reinterpret_cast<unsigned char *> (regTemplate.data()), regTemplate.size());}int FingerprintCacheDB::deleteItem(unsigned int fingerID){return ZKFPM_DBDel(m_hDBCache, fingerID);}int FingerprintCacheDB::count() const{if(m_hDBCache){int c;ZKFPM_DBCount(m_hDBCache, reinterpret_cast<unsigned int*> (&c));return c;}return 0;}int FingerprintCacheDB::verifyFinger(QByteArray regTemplate, QByteArray verTemplate){if(m_hDBCache){int score = ZKFPM_DBMatch(m_hDBCache,reinterpret_cast<unsigned char *> (regTemplate.data()), regTemplate.size(),reinterpret_cast<unsigned char *> (verTemplate.data()), verTemplate.size());return score;}return -1;}int FingerprintCacheDB::mergeFinger(QByteArray in1, QByteArray in2, QByteArray in3, QByteArray &outTemplate){if(m_hDBCache){unsigned int cbRegTemp = MAX_TEMPLATE_SIZE;outTemplate.resize(MAX_TEMPLATE_SIZE);outTemplate.fill(0);int ret = ZKFPM_DBMerge(m_hDBCache,reinterpret_cast<unsigned char *> (in1.data()),reinterpret_cast<unsigned char *> (in2.data()),reinterpret_cast<unsigned char *> (in3.data()),reinterpret_cast<unsigned char *> (outTemplate.data()), &cbRegTemp);outTemplate.resize(cbRegTemp);return ret;}return -1;}int FingerprintCacheDB::identify(QString base64String, unsigned int &fingerID, unsigned int &score){QByteArray fpTemp = Base64ToBlob(base64String);return identify(fpTemp, fingerID, score);}int FingerprintCacheDB::identify(QByteArray inTemplate, unsigned int &fingerID, unsigned int &score){return ZKFPM_DBIdentify(m_hDBCache,reinterpret_cast<unsigned char *> (inTemplate.data()), inTemplate.size(),&fingerID, &score);}}

FingerprintEnroll

FingerprintEnroll 用于将同一手指的三次采集到的指纹模板合成一个指纹模板。样合成后的指纹模板包含指纹信息更全面,判别准确率更高。这个过程的核心是个状态机,中间要判断每次获得的指纹是否合适,并剔除不合理的指纹。

下面是头文件;

#ifndef FINGERPRINTENROLL_H#define FINGERPRINTENROLL_H/****/#include <QObject>#include <QByteArray>#include <QImage>namespace ZKFP{class FingerprintReader;class FingerprintCacheDB;/*** @brief The FingerprintEnroll class 辅助类,用于将同一手指的三次采集到的指纹模板合成一个指纹模板*这样合成后的指纹模板包含指纹信息更全面,判别准确率更高。*其实这个过程不应该叫 enroll, enroll 应该包括将结果注册到数据库中。*但是没想好更好的词,所以暂时就叫这个词吧。*/class FingerprintEnroll : public QObject{Q_OBJECTpublic:explicit FingerprintEnroll(FingerprintCacheDB *cacheDB = nullptr, QObject *parent = nullptr);void setFingerprintCacheDB(FingerprintCacheDB *cacheDB);QByteArray regTemplate() const {return m_regTemplate;}signals:void enrollFinished(QByteArray regTemplate);void enrollFailed();void fingerprintRejected();void fingerprintAccepted();public slots:void reset();bool addFPTemplate(QByteArray fpTemplate);bool addFingerprint(QImage fingerImage, QByteArray fpTemplate);void beginEnroll(ZKFP::FingerprintReader * reader);void cancelEnroll();private:FingerprintReader * m_reader;FingerprintCacheDB *m_cacheDB;QByteArray m_fpTemplate[3];QByteArray m_regTemplate;bool m_bRegister;int m_enrollIdx;};}#endif // FINGERPRINTENROLL_H

之后是 cpp 文件:

#include "FingerprintEnroll.h"#include "FingerprintCacheDB.h"#include "FingerprintReader.h"#include <QDebug>namespace ZKFP{static const int ENROLLCNT = 3;FingerprintEnroll::FingerprintEnroll(FingerprintCacheDB *cacheDB, QObject *parent): QObject(parent),m_cacheDB(0),m_reader(0),m_enrollIdx(0),m_bRegister(false){m_cacheDB = cacheDB;}void FingerprintEnroll::setFingerprintCacheDB(FingerprintCacheDB *cacheDB){m_cacheDB = cacheDB;}void FingerprintEnroll::reset(){if(m_cacheDB && m_reader){disconnect(m_reader, SIGNAL(onFingerprintReceived(QImage,QByteArray)),this, SLOT(addFingerprint(QImage,QByteArray)));}m_enrollIdx = 0;m_bRegister = false;m_regTemplate.clear();m_fpTemplate[0].clear();m_fpTemplate[1].clear();m_fpTemplate[2].clear();}void FingerprintEnroll::beginEnroll(FingerprintReader * reader){reset();m_reader = reader;if(m_cacheDB && m_reader){connect(m_reader, SIGNAL(onFingerprintReceived(QImage,QByteArray)),this, SLOT(addFingerprint(QImage,QByteArray)));}m_reader->beginCapture();}void FingerprintEnroll::cancelEnroll(){reset();m_reader->cancelCapture();}bool FingerprintEnroll::addFingerprint(QImage fingerImage, QByteArray fpTemplate){Q_UNUSED(fingerImage);return addFPTemplate(fpTemplate);}bool FingerprintEnroll::addFPTemplate(QByteArray fpTemplate){qDebug() << "m_enrollIdx = " << m_enrollIdx;if(m_cacheDB == 0){return false;}if (m_enrollIdx >= ENROLLCNT){//reset();return false;}if (m_enrollIdx > 0){int score = m_cacheDB->verifyFinger(m_fpTemplate[m_enrollIdx - 1], fpTemplate);qDebug() << "score = " << score;if (score <= 0){//m_enrollIdx = 0;//m_bRegister = false;emit fingerprintRejected();qDebug() << "fingerprintRejected()";return false;}}m_fpTemplate[m_enrollIdx] = fpTemplate;if (++m_enrollIdx >= ENROLLCNT){int ret = m_cacheDB->mergeFinger(m_fpTemplate[0], m_fpTemplate[1], m_fpTemplate[2], m_regTemplate);//m_enrollIdx = 0;m_bRegister = FALSE;if (0 == ret){emit enrollFinished(m_regTemplate);disconnect(m_reader, SIGNAL(onFingerprintReceived(QImage,QByteArray)),this, SLOT(addFingerprint(QImage,QByteArray)));m_reader->cancelCapture();qDebug() << "enrollFinished()";return true;}else{emit enrollFailed();disconnect(m_reader, SIGNAL(onFingerprintReceived(QImage,QByteArray)),this, SLOT(addFingerprint(QImage,QByteArray)));qDebug() << "enrollFailed()";return false;}if(m_reader){disconnect(m_reader, SIGNAL(onFingerprintReceived(QImage,QByteArray)),this, SLOT(addFingerprint(QImage,QByteArray)));}}else{emit fingerprintAccepted();qDebug() << "fingerprintAccepted()";return true;}return false;}}

FPCacheDBLoader

FPCacheDBLoader 是个数据库代码。用于将指纹存储到数据库,或者从数据库中读出。因为功能比较见到那,所以使用的是 SQLite。这个数据库功能比较少,但是对这个项目来说也足够了。这个代码只是个示例,不同的项目中肯定还要根据具体的需求来改写。

下面是头文件:

#ifndef FPCACHEDBLOADER_H#define FPCACHEDBLOADER_H#include <QObject>#include <QList>#include <QString>#include <QMap>#include <QSql>#include <QSqlDatabase>namespace ZKFP{class FingerprintCacheDB;/*** @brief The FPCacheDBLoader class 辅助类,用于加载指纹数据库。*/class FPCacheDBLoader : public QObject{Q_OBJECTpublic:explicit FPCacheDBLoader(QObject *parent = nullptr);/*** @brief loadFromFile 从文件中加载指纹数据库,并将指纹数据送到 db* @param fileName 保存指纹数据的文件* @param db* @return true 表示成功, false 表示失败*/bool loadFromFile(QString fileName, FingerprintCacheDB *fpDB);void initFPCacheDB(FingerprintCacheDB *fpDB);QList<int> userIDs();QString userName(int userID);QMap<int, QString> userNames();bool userInfo(int userID, QString &name, QString &password, QByteArray &fpTemplate);bool addUser(int userID, QString name, QString password, QByteArray fpTemplate);bool deleteUser(int userID);signals:public slots:private:QSqlDatabase m_database;};}#endif // FPCACHEDBLOADER_H

之后是 cpp 文件:

#include "FPCacheDBLoader.h"#include <QSqlQuery>#include <QDebug>#include <QDir>#include <QStandardPaths>#include "ZKFingerReader/FingerprintCacheDB.h"namespace ZKFP{FPCacheDBLoader::FPCacheDBLoader(QObject *parent) : QObject(parent){m_database = QSqlDatabase::addDatabase("QSQLITE");QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);QDir dir;dir.mkdir(path);path += "/fingerprintDB.db";qDebug() << path;m_database.setDatabaseName(path);m_database.open();QSqlQuery query(m_database);query.exec("CREATE TABLE IF NOT EXISTS [fingerprint](""user_id INTEGER NOT NULL UNIQUE,""name TEXT,""password TEXT,""fingerprint BLOB);");}QMap<int, QString> FPCacheDBLoader::userNames(){QSqlQuery query(m_database);query.setForwardOnly(true);query.prepare("SELECT user_id, name FROM fingerprint");query.exec();QMap<int, QString> names;while( query.next( ) ){int id = query.value(0).toInt();QString name = query.value(1).toString();names[id] = name;}return names;}QList<int> FPCacheDBLoader::userIDs(){QSqlQuery query(m_database);query.setForwardOnly(true);query.prepare("SELECT user_id FROM fingerprint");query.exec();QList<int> IDs;while( query.next( ) ){int id = query.value(0).toInt();IDs << id;}return IDs;}bool FPCacheDBLoader::addUser(int userID, QString name, QString password, QByteArray fpTemplate){QSqlQuery query(m_database);query.prepare("INSERT into fingerprint(user_id, name, password, fingerprint) VALUES(:user_id, :name,:password, :fingerprint) ;");query.bindValue(":user_id", userID);query.bindValue(":name", name);query.bindValue(":password", password);query.bindValue(":fingerprint", fpTemplate);return query.exec();}bool FPCacheDBLoader::userInfo(int userID, QString &name, QString &password, QByteArray &fpTemplate){QSqlQuery query(m_database);query.setForwardOnly(true);query.prepare("SELECT * FROM fingerprint WHERE user_id = :id");query.bindValue(":id", userID);query.exec();if( query.next( ) ){name = query.value(1).toString();password = query.value(2).toString();fpTemplate = query.value(3).toByteArray();return true;}return false;}bool FPCacheDBLoader::deleteUser(int userID){QSqlQuery query(m_database);query.prepare("DELETE FROM fingerprint WHERE user_id = :id");query.bindValue(":id", userID);return query.exec();}QString FPCacheDBLoader::userName(int userID){QSqlQuery query(m_database);query.setForwardOnly(true);query.prepare("SELECT name FROM fingerprint WHERE user_id = :id");query.bindValue(":id", userID);query.exec();if( query.next( ) ){QString name = query.value(0).toString();return name;}return QString();}void FPCacheDBLoader::initFPCacheDB(FingerprintCacheDB *fpDB){fpDB->clearAll();QSqlQuery query(m_database);query.setForwardOnly(true);query.exec("SELECT user_id, fingerprint FROM fingerprint");while( query.next( ) ){int fid = query.value(0).toInt();QByteArray fpTemplate = query.value(1).toByteArray();fpDB->addItem(fid, fpTemplate);qDebug() << "fid = " << fid;}}bool FPCacheDBLoader::loadFromFile(QString fileName, ZKFP::FingerprintCacheDB *fpDB){QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE");database.setDatabaseName(fileName);if(database.open()){qDebug() << "database open succ";fpDB->clearAll();QSqlQuery query(database);query.setForwardOnly(true);query.exec("SELECT user_id, fingerprint FROM fingerprint");while( query.next( ) ){int fid = query.value(0).toInt();QByteArray fpTemplate = query.value(1).toByteArray();fpDB->addItem(fid, fpTemplate);}return true;}return false;}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。